[NOD-1532] AlwaysCallResolveBlockStatus in BuildBlock + Fixes to make it work if there's nothing to resolve

This commit is contained in:
Mike Zak 2020-11-17 11:47:12 +02:00 committed by Svarog
parent dbd15aecf5
commit b2188f5993
2 changed files with 37 additions and 21 deletions

View File

@ -104,11 +104,9 @@ func (bb *testBlockBuilder) buildBlockWithParents(
return nil, err return nil, err
} }
if selectedParentStatus == externalapi.StatusUTXOPendingVerification { selectedParentStatus, err = bb.testConsensus.ConsensusStateManager().ResolveBlockStatus(ghostdagData.SelectedParent)
selectedParentStatus, err = bb.testConsensus.ConsensusStateManager().ResolveBlockStatus(ghostdagData.SelectedParent) if err != nil {
if err != nil { return nil, err
return nil, err
}
} }
if selectedParentStatus == externalapi.StatusDisqualifiedFromChain { if selectedParentStatus == externalapi.StatusDisqualifiedFromChain {
return nil, errors.Errorf("Error building block with selectedParent %s with status DisqualifiedFromChain", return nil, errors.Errorf("Error building block with selectedParent %s with status DisqualifiedFromChain",

View File

@ -10,7 +10,7 @@ import (
func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error) { func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error) {
// get list of all blocks in the selected parent chain that have not yet resolved their status // get list of all blocks in the selected parent chain that have not yet resolved their status
unverifiedBlocks, selectedParentStatus, err := csm.getUnverifiedChainBlocksAndSelectedParentStatus(blockHash) unverifiedBlocks, err := csm.getUnverifiedChainBlocks(blockHash)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -21,6 +21,11 @@ func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.Doma
return csm.blockStatusStore.Get(csm.databaseContext, blockHash) return csm.blockStatusStore.Get(csm.databaseContext, blockHash)
} }
selectedParentStatus, err := csm.findSelectedParentStatus(unverifiedBlocks)
if err != nil {
return 0, err
}
var blockStatus externalapi.BlockStatus var blockStatus externalapi.BlockStatus
// resolve the unverified blocks' statuses in opposite order // resolve the unverified blocks' statuses in opposite order
for i := len(unverifiedBlocks) - 1; i >= 0; i-- { for i := len(unverifiedBlocks) - 1; i >= 0; i-- {
@ -42,33 +47,46 @@ func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.Doma
return blockStatus, nil return blockStatus, nil
} }
func (csm *consensusStateManager) getUnverifiedChainBlocksAndSelectedParentStatus(blockHash *externalapi.DomainHash) ( // findSelectedParentStatus returns the status of the selectedParent of the last block in the unverifiedBlocks chain
[]*externalapi.DomainHash, externalapi.BlockStatus, error) { func (csm *consensusStateManager) findSelectedParentStatus(unverifiedBlocks []*externalapi.DomainHash) (
externalapi.BlockStatus, error) {
lastUnverifiedBlock := unverifiedBlocks[len(unverifiedBlocks)-1]
if *lastUnverifiedBlock == *csm.genesisHash {
return externalapi.StatusValid, nil
}
lastUnverifiedBlockGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, lastUnverifiedBlock)
if err != nil {
return 0, err
}
return csm.blockStatusStore.Get(csm.databaseContext, lastUnverifiedBlockGHOSTDAGData.SelectedParent)
}
unverifiedBlocks := []*externalapi.DomainHash{blockHash} func (csm *consensusStateManager) getUnverifiedChainBlocks(
blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
unverifiedBlocks := []*externalapi.DomainHash{}
currentHash := blockHash currentHash := blockHash
for { for {
ghostdagData, err := csm.ghostdagDataStore.Get(csm.databaseContext, currentHash) currentBlockStatus, err := csm.blockStatusStore.Get(csm.databaseContext, currentHash)
if err != nil { if err != nil {
return nil, 0, err return nil, err
}
if currentBlockStatus != externalapi.StatusUTXOPendingVerification {
return unverifiedBlocks, nil
} }
if ghostdagData.SelectedParent == nil { unverifiedBlocks = append(unverifiedBlocks, currentHash)
return unverifiedBlocks, externalapi.StatusValid, nil
}
selectedParentStatus, err := csm.blockStatusStore.Get(csm.databaseContext, ghostdagData.SelectedParent) currentBlockGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, currentHash)
if err != nil { if err != nil {
return nil, 0, err return nil, err
} }
if selectedParentStatus != externalapi.StatusUTXOPendingVerification { if currentBlockGHOSTDAGData.SelectedParent == nil {
return unverifiedBlocks, selectedParentStatus, nil return unverifiedBlocks, nil // this means we reached genesis
} }
unverifiedBlocks = append(unverifiedBlocks, ghostdagData.SelectedParent) currentHash = currentBlockGHOSTDAGData.SelectedParent
currentHash = ghostdagData.SelectedParent
} }
} }