ExpectedHeaderPruningPoint fix (#1876)

* ExpectedHeaderPruningPoint fix

* Fix off by one error when iterating lowHash's selected chain
This commit is contained in:
Ori Newman 2021-12-11 19:26:35 +02:00 committed by GitHub
parent 70900c571b
commit 2a97b7c9bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 7 deletions

View File

@ -588,7 +588,7 @@ func dagStores(config *Config,
ghostdagDataStores[i] = ghostdagdatastore.New(prefixBucket, ghostdagDataCacheSize, preallocateCaches)
} else {
blockRelationStores[i] = blockrelationstore.New(prefixBucket, 200, false)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, 86400, false)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, pruningWindowSizePlusFinalityDepthForCache, false)
ghostdagDataStores[i] = ghostdagdatastore.New(prefixBucket, 200, false)
}
}

View File

@ -8,7 +8,7 @@ type DAGTraversalManager interface {
LowestChainBlockAboveOrEqualToBlueScore(stagingArea *StagingArea, highHash *externalapi.DomainHash, blueScore uint64) (*externalapi.DomainHash, error)
// SelectedChildIterator should return a BlockIterator that iterates
// from lowHash (exclusive) to highHash (inclusive) over highHash's selected parent chain
SelectedChildIterator(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash) (BlockIterator, error)
SelectedChildIterator(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash, includeLowHash bool) (BlockIterator, error)
SelectedChild(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash) (*externalapi.DomainHash, error)
AnticoneFromBlocks(stagingArea *StagingArea, tips []*externalapi.DomainHash, blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error)
AnticoneFromVirtualPOV(stagingArea *StagingArea, blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error)

View File

@ -9,6 +9,7 @@ import (
type selectedChildIterator struct {
dagTraversalManager model.DAGTraversalManager
includeLowHash bool
highHash, lowHash *externalapi.DomainHash
current *externalapi.DomainHash
err error
@ -21,6 +22,10 @@ func (s *selectedChildIterator) First() bool {
panic("Tried using a closed SelectedChildIterator")
}
s.current = s.lowHash
if s.includeLowHash {
return true
}
return s.Next()
}
@ -67,7 +72,9 @@ func (s *selectedChildIterator) Close() error {
// SelectedChildIterator returns a BlockIterator that iterates from lowHash (exclusive) to highHash (inclusive) over
// highHash's selected parent chain
func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.StagingArea, highHash, lowHash *externalapi.DomainHash) (model.BlockIterator, error) {
func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.StagingArea,
highHash, lowHash *externalapi.DomainHash, includeLowHash bool) (model.BlockIterator, error) {
isLowHashInSelectedParentChainOfHighHash, err := dtm.dagTopologyManager.IsInSelectedParentChainOf(
stagingArea, lowHash, highHash)
if err != nil {
@ -79,6 +86,7 @@ func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.Staging
}
return &selectedChildIterator{
dagTraversalManager: dtm,
includeLowHash: includeLowHash,
highHash: highHash,
lowHash: lowHash,
current: lowHash,

View File

@ -219,7 +219,7 @@ func (pm *pruningManager) nextPruningPointAndCandidateByBlockHash(stagingArea *m
// We iterate until the selected parent of the given block, in order to allow a situation where the given block hash
// belongs to the virtual. This shouldn't change anything since the max blue score difference between a block and its
// selected parent is K, and K << pm.pruningDepth.
iterator, err := pm.dagTraversalManager.SelectedChildIterator(stagingArea, ghostdagData.SelectedParent(), lowHash)
iterator, err := pm.dagTraversalManager.SelectedChildIterator(stagingArea, ghostdagData.SelectedParent(), lowHash, true)
if err != nil {
return nil, nil, err
}
@ -1051,7 +1051,19 @@ func (pm *pruningManager) ExpectedHeaderPruningPoint(stagingArea *model.StagingA
}
nextOrCurrentPruningPoint := selectedParentHeader.PruningPoint()
if pm.finalityScore(ghostdagData.BlueScore()) > pm.finalityScore(selectedParentPruningPointHeader.BlueScore()+pm.pruningDepth) {
pruningPoint, err := pm.pruningStore.PruningPoint(pm.databaseContext, stagingArea)
if err != nil {
return nil, err
}
// If the block doesn't have the pruning in its selected chain we know for sure that it can't trigger a pruning point
// change (we check the selected parent to take care of the case where the block is the virtual which doesn't have reachability data).
hasPruningPointInItsSelectedChain, err := pm.dagTopologyManager.IsInSelectedParentChainOf(stagingArea, pruningPoint, ghostdagData.SelectedParent())
if err != nil {
return nil, err
}
if hasPruningPointInItsSelectedChain && pm.finalityScore(ghostdagData.BlueScore()) > pm.finalityScore(selectedParentPruningPointHeader.BlueScore()+pm.pruningDepth) {
var suggestedLowHash *externalapi.DomainHash
hasReachabilityData, err := pm.reachabilityDataStore.HasReachabilityData(pm.databaseContext, stagingArea, selectedParentHeader.PruningPoint())
if err != nil {

View File

@ -46,7 +46,7 @@ func (sm *syncManager) antiPastHashesBetween(stagingArea *model.StagingArea, low
// Collect all hashes by concatenating the merge-sets of all blocks between highHash and lowHash
blockHashes := []*externalapi.DomainHash{}
iterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, lowHash)
iterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, lowHash, false)
if err != nil {
return nil, nil, err
}
@ -121,7 +121,7 @@ func (sm *syncManager) missingBlockBodyHashes(stagingArea *model.StagingArea, hi
return nil, err
}
selectedChildIterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, pruningPoint)
selectedChildIterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, pruningPoint, false)
if err != nil {
return nil, err
}