Improve ExpectedHeaderPruningPoint performance (#1833)

* Improve ExpectedHeaderPruningPoint perf

* Add suggestedLowHash to nextPruningPointAndCandidateByBlockHash
This commit is contained in:
Ori Newman 2021-10-26 11:01:26 +03:00 committed by GitHub
parent 5dbb1da84b
commit 1b9be28613
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 10 deletions

View File

@ -558,7 +558,7 @@ func dagStores(config *Config,
reachabilityDataStores := make([]model.ReachabilityDataStore, constants.MaxBlockLevel+1)
ghostdagDataStores := make([]model.GHOSTDAGDataStore, constants.MaxBlockLevel+1)
ghostdagDataCacheSize := pruningWindowSizeForCaches
ghostdagDataCacheSize := pruningWindowSizeForCaches * 2
if ghostdagDataCacheSize < config.DifficultyAdjustmentWindowSize {
ghostdagDataCacheSize = config.DifficultyAdjustmentWindowSize
}
@ -567,7 +567,7 @@ func dagStores(config *Config,
prefixBucket := prefixBucket.Bucket([]byte{byte(i)})
if i == 0 {
blockRelationStores[i] = blockrelationstore.New(prefixBucket, pruningWindowSizePlusFinalityDepthForCache, preallocateCaches)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, pruningWindowSizePlusFinalityDepthForCache, preallocateCaches)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, pruningWindowSizePlusFinalityDepthForCache*2, preallocateCaches)
ghostdagDataStores[i] = ghostdagdatastore.New(prefixBucket, ghostdagDataCacheSize, preallocateCaches)
} else {
blockRelationStores[i] = blockrelationstore.New(prefixBucket, 200, false)

View File

@ -13,7 +13,5 @@ type PruningManager interface {
UpdatePruningPointIfRequired() error
PruneAllBlocksBelow(stagingArea *StagingArea, pruningPointHash *externalapi.DomainHash) error
PruningPointAndItsAnticoneWithTrustedData() ([]*externalapi.BlockWithTrustedData, error)
NextPruningPointAndCandidateByBlockHash(stagingArea *StagingArea,
blockHash *externalapi.DomainHash) (*externalapi.DomainHash, *externalapi.DomainHash, error)
ExpectedHeaderPruningPoint(stagingArea *StagingArea, blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error)
}

View File

@ -138,7 +138,7 @@ func (pm *pruningManager) UpdatePruningPointByVirtual(stagingArea *model.Staging
return err
}
newPruningPoint, newCandidate, err := pm.NextPruningPointAndCandidateByBlockHash(stagingArea, virtualGHOSTDAGData.SelectedParent())
newPruningPoint, newCandidate, err := pm.nextPruningPointAndCandidateByBlockHash(stagingArea, virtualGHOSTDAGData.SelectedParent(), nil)
if err != nil {
return err
}
@ -169,10 +169,10 @@ func (pm *pruningManager) UpdatePruningPointByVirtual(stagingArea *model.Staging
return nil
}
func (pm *pruningManager) NextPruningPointAndCandidateByBlockHash(stagingArea *model.StagingArea,
blockHash *externalapi.DomainHash) (*externalapi.DomainHash, *externalapi.DomainHash, error) {
func (pm *pruningManager) nextPruningPointAndCandidateByBlockHash(stagingArea *model.StagingArea,
blockHash, suggestedLowHash *externalapi.DomainHash) (*externalapi.DomainHash, *externalapi.DomainHash, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "pruningManager.NextPruningPointAndCandidateByBlockHash")
onEnd := logger.LogAndMeasureExecutionTime(log, "pruningManager.nextPruningPointAndCandidateByBlockHash")
defer onEnd()
currentCandidate, err := pm.pruningPointCandidate(stagingArea)
@ -180,6 +180,26 @@ func (pm *pruningManager) NextPruningPointAndCandidateByBlockHash(stagingArea *m
return nil, nil, err
}
lowHash := currentCandidate
if suggestedLowHash != nil {
isSuggestedLowHashInSelectedParentChainOfCurrentCandidate, err := pm.dagTopologyManager.IsInSelectedParentChainOf(stagingArea, suggestedLowHash, currentCandidate)
if err != nil {
return nil, nil, err
}
if !isSuggestedLowHashInSelectedParentChainOfCurrentCandidate {
isCurrentCandidateInSelectedParentChainOfSuggestedLowHash, err := pm.dagTopologyManager.IsInSelectedParentChainOf(stagingArea, currentCandidate, suggestedLowHash)
if err != nil {
return nil, nil, err
}
if !isCurrentCandidateInSelectedParentChainOfSuggestedLowHash {
panic(errors.Errorf("suggested low hash %s is not on the same selected chain as the pruning candidate %s", suggestedLowHash, currentCandidate))
}
lowHash = suggestedLowHash
}
}
ghostdagData, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, blockHash, false)
if err != nil {
return nil, nil, err
@ -198,7 +218,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(), currentCandidate)
iterator, err := pm.dagTraversalManager.SelectedChildIterator(stagingArea, ghostdagData.SelectedParent(), lowHash)
if err != nil {
return nil, nil, err
}
@ -960,11 +980,43 @@ func (pm *pruningManager) blockWithTrustedData(stagingArea *model.StagingArea, b
}
func (pm *pruningManager) ExpectedHeaderPruningPoint(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
nextOrCurrentPruningPoint, _, err := pm.NextPruningPointAndCandidateByBlockHash(stagingArea, blockHash)
ghostdagData, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, blockHash, false)
if err != nil {
return nil, err
}
if ghostdagData.SelectedParent().Equal(pm.genesisHash) {
return pm.genesisHash, nil
}
selectedParentHeader, err := pm.blockHeaderStore.BlockHeader(pm.databaseContext, stagingArea, ghostdagData.SelectedParent())
if err != nil {
return nil, err
}
selectedParentPruningPointHeader, err := pm.blockHeaderStore.BlockHeader(pm.databaseContext, stagingArea, selectedParentHeader.PruningPoint())
if err != nil {
return nil, err
}
nextOrCurrentPruningPoint := selectedParentHeader.PruningPoint()
if 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 {
return nil, err
}
if hasReachabilityData {
suggestedLowHash = selectedParentHeader.PruningPoint()
}
nextOrCurrentPruningPoint, _, err = pm.nextPruningPointAndCandidateByBlockHash(stagingArea, blockHash, suggestedLowHash)
if err != nil {
return nil, err
}
}
isHeaderPruningPoint, err := pm.isPruningPointInPruningDepth(stagingArea, blockHash, nextOrCurrentPruningPoint)
if err != nil {
return nil, err