mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-23 14:32:32 +00:00

* Pruning headers p2p basic structure * Remove headers-first * Fix consensus tests except TestValidateAndInsertPruningPointWithSideBlocks and TestValidateAndInsertImportedPruningPoint * Add virtual genesis * Implement PruningPointAndItsAnticoneWithMetaData * Start fixing TestValidateAndInsertImportedPruningPoint * Fix TestValidateAndInsertImportedPruningPoint * Fix BlockWindow * Update p2p and gRPC * Fix all tests except TestHandleRelayInvs * Delete TestHandleRelayInvs parts that cover the old IBD flow * Fix lint errors * Add p2p_request_ibd_blocks.go * Clean code * Make MsgBlockWithMetaData implement its own representation * Remove redundant check if highest share block is below the pruning point * Fix TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime * Fix comments, errors ane names * Fix window size to the real value * Check reindex root after each block at TestUpdateReindexRoot * Remove irrelevant check * Renames and comments * Remove redundant argument from sendGetBlockLocator * Don't delete staging on non-recoverable errors * Renames and comments * Remove redundant code * Commit changes inside ResolveVirtual * Add comment to IsRecoverableError * Remove blocksWithMetaDataGHOSTDAGDataStore * Increase windows pagefile * Move DeleteStagingConsensus outside of defer * Get rid of mustAccepted in receiveBlockWithMetaData * Ban on invalid pruning point * Rename interface_datastructures_daawindowstore.go to interface_datastructures_blocks_with_meta_data_daa_window_store.go * * Change GetVirtualSelectedParentChainFromBlockResponseMessage and VirtualSelectedParentChainChangedNotificationMessage to show only added block hashes * Remove ResolveVirtual * Use externalapi.ConsensusWrapper inside MiningManager * Fix pruningmanager.blockwithmetadata * Set pruning point selected child when importing the pruning point UTXO set * Change virtual genesis hash * replace the selected parent with virtual genesis on removePrunedBlocksFromGHOSTDAGData * Get rid of low hash in block locators * Remove +1 from everywhere we use difficultyAdjustmentWindowSize and increase the default value by one * Add comments about consensus wrapper * Don't use separate staging area when resolving resolveBlockStatus * Fix netsync stability test * Fix checkResolveVirtual * Rename ConsensusWrapper->ConsensusReference * Get rid of blockHeapNode * Add comment to defaultDifficultyAdjustmentWindowSize * Add SelectedChild to DAGTraversalManager * Remove redundant copy * Rename blockWindowHeap->calculateBlockWindowHeap * Move isVirtualGenesisOnlyParent to utils * Change BlockWithMetaData->BlockWithTrustedData * Get rid of maxReasonLength * Split IBD to 100 blocks each time * Fix a bug in calculateBlockWindowHeap * Switch to trusted data when encountering virtual genesis in blockWithTrustedData * Move ConsensusReference to domain * Update ConsensusReference comment * Add comment * Rename shouldNotAddGenesis->skipAddingGenesis
129 lines
4.2 KiB
Go
129 lines
4.2 KiB
Go
package finalitymanager
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus/database"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
)
|
|
|
|
type finalityManager struct {
|
|
databaseContext model.DBReader
|
|
dagTopologyManager model.DAGTopologyManager
|
|
finalityStore model.FinalityStore
|
|
ghostdagDataStore model.GHOSTDAGDataStore
|
|
genesisHash *externalapi.DomainHash
|
|
finalityDepth uint64
|
|
}
|
|
|
|
// New instantiates a new FinalityManager
|
|
func New(databaseContext model.DBReader,
|
|
dagTopologyManager model.DAGTopologyManager,
|
|
finalityStore model.FinalityStore,
|
|
ghostdagDataStore model.GHOSTDAGDataStore,
|
|
genesisHash *externalapi.DomainHash,
|
|
finalityDepth uint64) model.FinalityManager {
|
|
|
|
return &finalityManager{
|
|
databaseContext: databaseContext,
|
|
genesisHash: genesisHash,
|
|
dagTopologyManager: dagTopologyManager,
|
|
finalityStore: finalityStore,
|
|
ghostdagDataStore: ghostdagDataStore,
|
|
finalityDepth: finalityDepth,
|
|
}
|
|
}
|
|
|
|
func (fm *finalityManager) VirtualFinalityPoint(stagingArea *model.StagingArea) (*externalapi.DomainHash, error) {
|
|
log.Debugf("virtualFinalityPoint start")
|
|
defer log.Debugf("virtualFinalityPoint end")
|
|
|
|
virtualFinalityPoint, err := fm.calculateFinalityPoint(stagingArea, model.VirtualBlockHash, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
log.Debugf("The current virtual finality block is: %s", virtualFinalityPoint)
|
|
|
|
return virtualFinalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) FinalityPoint(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (*externalapi.DomainHash, error) {
|
|
log.Debugf("FinalityPoint start")
|
|
defer log.Debugf("FinalityPoint end")
|
|
if blockHash.Equal(model.VirtualBlockHash) {
|
|
return fm.VirtualFinalityPoint(stagingArea)
|
|
}
|
|
finalityPoint, err := fm.finalityStore.FinalityPoint(fm.databaseContext, stagingArea, blockHash)
|
|
if err != nil {
|
|
log.Debugf("%s finality point not found in store - calculating", blockHash)
|
|
if errors.Is(err, database.ErrNotFound) {
|
|
return fm.calculateAndStageFinalityPoint(stagingArea, blockHash, isBlockWithTrustedData)
|
|
}
|
|
return nil, err
|
|
}
|
|
return finalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) calculateAndStageFinalityPoint(
|
|
stagingArea *model.StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (*externalapi.DomainHash, error) {
|
|
|
|
finalityPoint, err := fm.calculateFinalityPoint(stagingArea, blockHash, isBlockWithTrustedData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fm.finalityStore.StageFinalityPoint(stagingArea, blockHash, finalityPoint)
|
|
return finalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) calculateFinalityPoint(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (
|
|
*externalapi.DomainHash, error) {
|
|
|
|
log.Debugf("calculateFinalityPoint start")
|
|
defer log.Debugf("calculateFinalityPoint end")
|
|
|
|
if isBlockWithTrustedData {
|
|
return model.VirtualGenesisBlockHash, nil
|
|
}
|
|
|
|
ghostdagData, err := fm.ghostdagDataStore.Get(fm.databaseContext, stagingArea, blockHash, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if ghostdagData.BlueScore() < fm.finalityDepth {
|
|
log.Debugf("%s blue score lower then finality depth - returning genesis as finality point", blockHash)
|
|
return fm.genesisHash, nil
|
|
}
|
|
|
|
selectedParent := ghostdagData.SelectedParent()
|
|
if selectedParent.Equal(fm.genesisHash) {
|
|
return fm.genesisHash, nil
|
|
}
|
|
|
|
current, err := fm.finalityStore.FinalityPoint(fm.databaseContext, stagingArea, ghostdagData.SelectedParent())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
requiredBlueScore := ghostdagData.BlueScore() - fm.finalityDepth
|
|
log.Debugf("%s's finality point is the one having the highest blue score lower then %d", blockHash, requiredBlueScore)
|
|
|
|
var next *externalapi.DomainHash
|
|
for {
|
|
next, err = fm.dagTopologyManager.ChildInSelectedParentChainOf(stagingArea, current, blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
nextGHOSTDAGData, err := fm.ghostdagDataStore.Get(fm.databaseContext, stagingArea, next, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if nextGHOSTDAGData.BlueScore() >= requiredBlueScore {
|
|
log.Debugf("%s's finality point is %s", blockHash, current)
|
|
return current, nil
|
|
}
|
|
|
|
current = next
|
|
}
|
|
}
|