diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index b795830cd..8cc959520 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -103,7 +103,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat dbManager, ghostdagDataStore, acceptanceDataStore) - headerTipsManager := headertipsmanager.New(dbManager, dagTopologyManager, headerTipsStore) + headerTipsManager := headertipsmanager.New(dbManager, dagTopologyManager, ghostdagManager, headerTipsStore) genesisHash := (*externalapi.DomainHash)(dagParams.GenesisHash) mergeDepthManager := mergedepthmanager.New( dagParams.FinalityDepth(), diff --git a/domain/consensus/model/interface_processes_ghostdagmanager.go b/domain/consensus/model/interface_processes_ghostdagmanager.go index d4433dc17..f7cbab390 100644 --- a/domain/consensus/model/interface_processes_ghostdagmanager.go +++ b/domain/consensus/model/interface_processes_ghostdagmanager.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // GHOSTDAGManager resolves and manages GHOSTDAG block data type GHOSTDAGManager interface { GHOSTDAG(blockHash *externalapi.DomainHash) error - ChooseSelectedParent(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (*externalapi.DomainHash, error) + ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *BlockGHOSTDAGData, blockHashB *externalapi.DomainHash, ghostdagDataB *BlockGHOSTDAGData) bool } diff --git a/domain/consensus/model/interface_processes_headertipsmanager.go b/domain/consensus/model/interface_processes_headertipsmanager.go index 3cdb73307..deea0f4c8 100644 --- a/domain/consensus/model/interface_processes_headertipsmanager.go +++ b/domain/consensus/model/interface_processes_headertipsmanager.go @@ -5,4 +5,5 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // HeaderTipsManager manages the state of the header tips type HeaderTipsManager interface { AddHeaderTip(hash *externalapi.DomainHash) error + SelectedTip() (*externalapi.DomainHash, error) } diff --git a/domain/consensus/processes/blockprocessor/validateandinsertblock.go b/domain/consensus/processes/blockprocessor/validateandinsertblock.go index d8eb5da42..682d75884 100644 --- a/domain/consensus/processes/blockprocessor/validateandinsertblock.go +++ b/domain/consensus/processes/blockprocessor/validateandinsertblock.go @@ -62,6 +62,11 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock) return err } + oldHeadersSelectedTip, err := bp.headerTipsManager.SelectedTip() + if err != nil { + return err + } + if mode.State == externalapi.SyncStateHeadersFirst { err = bp.headerTipsManager.AddHeaderTip(hash) if err != nil { @@ -81,6 +86,11 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock) bp.headerTipsStore.Stage(tips) } + err = bp.updateReachabilityReindexRoot(oldHeadersSelectedTip) + if err != nil { + return err + } + // Trigger pruning, which will check if the pruning point changed and delete the data if it did. err = bp.pruningManager.FindNextPruningPoint() if err != nil { @@ -90,6 +100,19 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock) return bp.commitAllChanges() } +func (bp *blockProcessor) updateReachabilityReindexRoot(oldHeadersSelectedTip *externalapi.DomainHash) error { + headersSelectedTip, err := bp.headerTipsManager.SelectedTip() + if err != nil { + return err + } + + if *headersSelectedTip == *oldHeadersSelectedTip { + return nil + } + + return bp.reachabilityManager.UpdateReindexRoot(headersSelectedTip) +} + func (bp *blockProcessor) checkBlockStatus(hash *externalapi.DomainHash, mode *externalapi.SyncInfo) error { exists, err := bp.blockStatusStore.Exists(bp.databaseContext, hash) if err != nil { diff --git a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go index 3b13bcb30..81b5b19de 100644 --- a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go +++ b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go @@ -24,11 +24,6 @@ func (csm *consensusStateManager) AddBlockToVirtual(blockHash *externalapi.Domai if err != nil { return err } - - err = csm.reachabilityManager.UpdateReindexRoot(blockHash) - if err != nil { - return err - } } } diff --git a/domain/consensus/processes/ghostdagmanager/compare.go b/domain/consensus/processes/ghostdagmanager/compare.go index c4d794a64..b5c16f27e 100644 --- a/domain/consensus/processes/ghostdagmanager/compare.go +++ b/domain/consensus/processes/ghostdagmanager/compare.go @@ -32,23 +32,25 @@ func (gm *ghostdagManager) less(blockHashA *externalapi.DomainHash, blockHashB * return chosenSelectedParent == blockHashB, nil } -func (gm *ghostdagManager) ChooseSelectedParent(blockHashA *externalapi.DomainHash, - blockHashB *externalapi.DomainHash) (*externalapi.DomainHash, error) { - - blockAGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, blockHashA) +func (gm *ghostdagManager) ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) { + selectedParent := blockHashes[0] + selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, selectedParent) if err != nil { return nil, err } - blockBGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, blockHashB) - if err != nil { - return nil, err + for _, blockHash := range blockHashes { + blockGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, blockHash) + if err != nil { + return nil, err + } + + if gm.Less(selectedParent, selectedParentGHOSTDAGData, blockHash, blockGHOSTDAGData) { + selectedParent = blockHash + selectedParentGHOSTDAGData = blockGHOSTDAGData + } } - if gm.Less(blockHashA, blockAGHOSTDAGData, blockHashB, blockBGHOSTDAGData) { - return blockHashB, nil - } - - return blockHashA, nil + return selectedParent, nil } func (gm *ghostdagManager) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *model.BlockGHOSTDAGData, diff --git a/domain/consensus/processes/headertipsmanager/headertipsmanager.go b/domain/consensus/processes/headertipsmanager/headertipsmanager.go index 79c419139..cc0ed7f21 100644 --- a/domain/consensus/processes/headertipsmanager/headertipsmanager.go +++ b/domain/consensus/processes/headertipsmanager/headertipsmanager.go @@ -8,16 +8,19 @@ import ( type headerTipsManager struct { databaseContext model.DBReader dagTopologyManager model.DAGTopologyManager + ghostdagManager model.GHOSTDAGManager headerTipsStore model.HeaderTipsStore } // New instantiates a new HeaderTipsManager func New(databaseContext model.DBReader, dagTopologyManager model.DAGTopologyManager, + ghostdagManager model.GHOSTDAGManager, headerTipsStore model.HeaderTipsStore) model.HeaderTipsManager { return &headerTipsManager{ databaseContext: databaseContext, dagTopologyManager: dagTopologyManager, + ghostdagManager: ghostdagManager, headerTipsStore: headerTipsStore, } } diff --git a/domain/consensus/processes/headertipsmanager/selected_tip.go b/domain/consensus/processes/headertipsmanager/selected_tip.go new file mode 100644 index 000000000..72629c57f --- /dev/null +++ b/domain/consensus/processes/headertipsmanager/selected_tip.go @@ -0,0 +1,12 @@ +package headertipsmanager + +import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + +func (h headerTipsManager) SelectedTip() (*externalapi.DomainHash, error) { + tips, err := h.headerTipsStore.Tips(h.databaseContext) + if err != nil { + return nil, err + } + + return h.ghostdagManager.ChooseSelectedParent(tips...) +}