diff --git a/domain/consensus/consensus.go b/domain/consensus/consensus.go index a5bcfed91..6db33d9df 100644 --- a/domain/consensus/consensus.go +++ b/domain/consensus/consensus.go @@ -134,7 +134,7 @@ func (s *consensus) GetBlockInfo(blockHash *externalapi.DomainHash) (*externalap return nil, err } - blockInfo.BlueScore = ghostdagData.BlueScore + blockInfo.BlueScore = ghostdagData.BlueScore() isBlockInHeaderPruningPointFuture, err := s.syncManager.IsBlockInHeaderPruningPointFuture(blockHash) if err != nil { @@ -196,7 +196,7 @@ func (s *consensus) GetVirtualSelectedParent() (*externalapi.DomainBlock, error) if err != nil { return nil, err } - return s.blockStore.Block(s.databaseContext, virtualGHOSTDAGData.SelectedParent) + return s.blockStore.Block(s.databaseContext, virtualGHOSTDAGData.SelectedParent()) } func (s *consensus) CreateBlockLocator(lowHash, highHash *externalapi.DomainHash) (externalapi.BlockLocator, error) { diff --git a/domain/consensus/database/serialization/block_ghostdag_data.go b/domain/consensus/database/serialization/block_ghostdag_data.go index 1765104ba..2b4a2544d 100644 --- a/domain/consensus/database/serialization/block_ghostdag_data.go +++ b/domain/consensus/database/serialization/block_ghostdag_data.go @@ -3,26 +3,27 @@ package serialization import ( "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager" ) // BlockGHOSTDAGDataToDBBlockGHOSTDAGData converts BlockGHOSTDAGData to DbBlockGhostdagData -func BlockGHOSTDAGDataToDBBlockGHOSTDAGData(blockGHOSTDAGData *model.BlockGHOSTDAGData) *DbBlockGhostdagData { +func BlockGHOSTDAGDataToDBBlockGHOSTDAGData(blockGHOSTDAGData model.BlockGHOSTDAGData) *DbBlockGhostdagData { var selectedParent *DbHash - if blockGHOSTDAGData.SelectedParent != nil { - selectedParent = DomainHashToDbHash(blockGHOSTDAGData.SelectedParent) + if blockGHOSTDAGData.SelectedParent() != nil { + selectedParent = DomainHashToDbHash(blockGHOSTDAGData.SelectedParent()) } return &DbBlockGhostdagData{ - BlueScore: blockGHOSTDAGData.BlueScore, + BlueScore: blockGHOSTDAGData.BlueScore(), SelectedParent: selectedParent, - MergeSetBlues: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetBlues), - MergeSetReds: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetReds), - BluesAnticoneSizes: bluesAnticoneSizesToDBBluesAnticoneSizes(blockGHOSTDAGData.BluesAnticoneSizes), + MergeSetBlues: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetBlues()), + MergeSetReds: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetReds()), + BluesAnticoneSizes: bluesAnticoneSizesToDBBluesAnticoneSizes(blockGHOSTDAGData.BluesAnticoneSizes()), } } // DBBlockGHOSTDAGDataToBlockGHOSTDAGData converts DbBlockGhostdagData to BlockGHOSTDAGData -func DBBlockGHOSTDAGDataToBlockGHOSTDAGData(dbBlockGHOSTDAGData *DbBlockGhostdagData) (*model.BlockGHOSTDAGData, error) { +func DBBlockGHOSTDAGDataToBlockGHOSTDAGData(dbBlockGHOSTDAGData *DbBlockGhostdagData) (model.BlockGHOSTDAGData, error) { var selectedParent *externalapi.DomainHash if dbBlockGHOSTDAGData.SelectedParent != nil { var err error @@ -47,11 +48,11 @@ func DBBlockGHOSTDAGDataToBlockGHOSTDAGData(dbBlockGHOSTDAGData *DbBlockGhostdag return nil, err } - return &model.BlockGHOSTDAGData{ - BlueScore: dbBlockGHOSTDAGData.BlueScore, - SelectedParent: selectedParent, - MergeSetBlues: mergetSetBlues, - MergeSetReds: mergetSetReds, - BluesAnticoneSizes: bluesAnticoneSizes, - }, nil + return ghostdagmanager.NewBlockGHOSTDAGData( + dbBlockGHOSTDAGData.BlueScore, + selectedParent, + mergetSetBlues, + mergetSetReds, + bluesAnticoneSizes, + ), nil } diff --git a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go index aaa096a16..c42a01402 100644 --- a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go +++ b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go @@ -13,21 +13,21 @@ var bucket = dbkeys.MakeBucket([]byte("block-ghostdag-data")) // ghostdagDataStore represents a store of BlockGHOSTDAGData type ghostdagDataStore struct { - staging map[externalapi.DomainHash]*model.BlockGHOSTDAGData + staging map[externalapi.DomainHash]model.BlockGHOSTDAGData cache *lrucache.LRUCache } // New instantiates a new GHOSTDAGDataStore func New(cacheSize int) model.GHOSTDAGDataStore { return &ghostdagDataStore{ - staging: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData), + staging: make(map[externalapi.DomainHash]model.BlockGHOSTDAGData), cache: lrucache.New(cacheSize), } } // Stage stages the given blockGHOSTDAGData for the given blockHash -func (gds *ghostdagDataStore) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) { - gds.staging[*blockHash] = blockGHOSTDAGData.Clone() +func (gds *ghostdagDataStore) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData model.BlockGHOSTDAGData) { + gds.staging[*blockHash] = blockGHOSTDAGData } func (gds *ghostdagDataStore) IsStaged() bool { @@ -35,7 +35,7 @@ func (gds *ghostdagDataStore) IsStaged() bool { } func (gds *ghostdagDataStore) Discard() { - gds.staging = make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData) + gds.staging = make(map[externalapi.DomainHash]model.BlockGHOSTDAGData) } func (gds *ghostdagDataStore) Commit(dbTx model.DBTransaction) error { @@ -56,13 +56,13 @@ func (gds *ghostdagDataStore) Commit(dbTx model.DBTransaction) error { } // Get gets the blockGHOSTDAGData associated with the given blockHash -func (gds *ghostdagDataStore) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) { +func (gds *ghostdagDataStore) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (model.BlockGHOSTDAGData, error) { if blockGHOSTDAGData, ok := gds.staging[*blockHash]; ok { - return blockGHOSTDAGData.Clone(), nil + return blockGHOSTDAGData, nil } if blockGHOSTDAGData, ok := gds.cache.Get(blockHash); ok { - return blockGHOSTDAGData.(*model.BlockGHOSTDAGData).Clone(), nil + return blockGHOSTDAGData.(model.BlockGHOSTDAGData), nil } blockGHOSTDAGDataBytes, err := dbContext.Get(gds.hashAsKey(blockHash)) @@ -75,18 +75,18 @@ func (gds *ghostdagDataStore) Get(dbContext model.DBReader, blockHash *externala return nil, err } gds.cache.Add(blockHash, blockGHOSTDAGData) - return blockGHOSTDAGData.Clone(), nil + return blockGHOSTDAGData, nil } func (gds *ghostdagDataStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey { return bucket.Key(hash[:]) } -func (gds *ghostdagDataStore) serializeBlockGHOSTDAGData(blockGHOSTDAGData *model.BlockGHOSTDAGData) ([]byte, error) { +func (gds *ghostdagDataStore) serializeBlockGHOSTDAGData(blockGHOSTDAGData model.BlockGHOSTDAGData) ([]byte, error) { return proto.Marshal(serialization.BlockGHOSTDAGDataToDBBlockGHOSTDAGData(blockGHOSTDAGData)) } -func (gds *ghostdagDataStore) deserializeBlockGHOSTDAGData(blockGHOSTDAGDataBytes []byte) (*model.BlockGHOSTDAGData, error) { +func (gds *ghostdagDataStore) deserializeBlockGHOSTDAGData(blockGHOSTDAGDataBytes []byte) (model.BlockGHOSTDAGData, error) { dbBlockGHOSTDAGData := &serialization.DbBlockGhostdagData{} err := proto.Unmarshal(blockGHOSTDAGDataBytes, dbBlockGHOSTDAGData) if err != nil { diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index 1e1aacddc..ca0db772f 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -63,24 +63,23 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat dbManager := consensusdatabase.New(db) // Data Structures - storeCacheSize := 200 - acceptanceDataStore := acceptancedatastore.New(storeCacheSize) - blockStore, err := blockstore.New(dbManager, storeCacheSize) + acceptanceDataStore := acceptancedatastore.New(200) + blockStore, err := blockstore.New(dbManager, 200) if err != nil { return nil, err } - blockHeaderStore, err := blockheaderstore.New(dbManager, storeCacheSize) + blockHeaderStore, err := blockheaderstore.New(dbManager, 10_000) if err != nil { return nil, err } - blockRelationStore := blockrelationstore.New(storeCacheSize) - blockStatusStore := blockstatusstore.New(storeCacheSize) - multisetStore := multisetstore.New(storeCacheSize) + blockRelationStore := blockrelationstore.New(200) + blockStatusStore := blockstatusstore.New(200) + multisetStore := multisetstore.New(200) pruningStore := pruningstore.New() - reachabilityDataStore := reachabilitydatastore.New(storeCacheSize) - utxoDiffStore := utxodiffstore.New(storeCacheSize) + reachabilityDataStore := reachabilitydatastore.New(200) + utxoDiffStore := utxodiffstore.New(200) consensusStateStore := consensusstatestore.New() - ghostdagDataStore := ghostdagdatastore.New(storeCacheSize) + ghostdagDataStore := ghostdagdatastore.New(10_000) headerTipsStore := headertipsstore.New() // Processes diff --git a/domain/consensus/finality_test.go b/domain/consensus/finality_test.go index 3beff0f45..61b0c3c12 100644 --- a/domain/consensus/finality_test.go +++ b/domain/consensus/finality_test.go @@ -155,7 +155,7 @@ func TestFinality(t *testing.T) { t.Fatalf("TestFinality: Failed getting the ghost dag data of the sidechain tip: %v", err) } - if selectedTipGhostDagData.BlueScore > sideChainTipGhostDagData.BlueScore { + if selectedTipGhostDagData.BlueScore() > sideChainTipGhostDagData.BlueScore() { t.Fatalf("sideChainTip is not the bluest tip when it is expected to be") } @@ -308,7 +308,7 @@ func TestBoundedMergeDepth(t *testing.T) { } // Make sure it's actually blue found := false - for _, blue := range virtualGhotDagData.MergeSetBlues { + for _, blue := range virtualGhotDagData.MergeSetBlues() { if *blue == *kosherizingBlockHash { found = true break @@ -356,7 +356,7 @@ func TestBoundedMergeDepth(t *testing.T) { } // Make sure it's actually blue found = false - for _, blue := range virtualGhotDagData.MergeSetBlues { + for _, blue := range virtualGhotDagData.MergeSetBlues() { if *blue == *kosherizingBlockHash { found = true break diff --git a/domain/consensus/model/ghostdag.go b/domain/consensus/model/ghostdag.go index d649c34aa..2f1b4370d 100644 --- a/domain/consensus/model/ghostdag.go +++ b/domain/consensus/model/ghostdag.go @@ -3,32 +3,12 @@ package model import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // BlockGHOSTDAGData represents GHOSTDAG data for some block -type BlockGHOSTDAGData struct { - BlueScore uint64 - SelectedParent *externalapi.DomainHash - MergeSetBlues []*externalapi.DomainHash - MergeSetReds []*externalapi.DomainHash - BluesAnticoneSizes map[externalapi.DomainHash]KType -} - -// Clone returns a clone of BlockGHOSTDAGData -func (bgd *BlockGHOSTDAGData) Clone() *BlockGHOSTDAGData { - if bgd == nil { - return nil - } - - bluesAnticoneSizesClone := make(map[externalapi.DomainHash]KType, len(bgd.BluesAnticoneSizes)) - for hash, size := range bgd.BluesAnticoneSizes { - bluesAnticoneSizesClone[hash] = size - } - - return &BlockGHOSTDAGData{ - BlueScore: bgd.BlueScore, - SelectedParent: bgd.SelectedParent.Clone(), - MergeSetBlues: externalapi.CloneHashes(bgd.MergeSetBlues), - MergeSetReds: externalapi.CloneHashes(bgd.MergeSetReds), - BluesAnticoneSizes: bluesAnticoneSizesClone, - } +type BlockGHOSTDAGData interface { + BlueScore() uint64 + SelectedParent() *externalapi.DomainHash + MergeSetBlues() []*externalapi.DomainHash + MergeSetReds() []*externalapi.DomainHash + BluesAnticoneSizes() map[externalapi.DomainHash]KType } // KType defines the size of GHOSTDAG consensus algorithm K parameter. diff --git a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go index 13522feb1..4e20e3408 100644 --- a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go +++ b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // GHOSTDAGDataStore represents a store of BlockGHOSTDAGData type GHOSTDAGDataStore interface { Store - Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) + Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData BlockGHOSTDAGData) IsStaged() bool - Get(dbContext DBReader, blockHash *externalapi.DomainHash) (*BlockGHOSTDAGData, error) + Get(dbContext DBReader, blockHash *externalapi.DomainHash) (BlockGHOSTDAGData, error) } diff --git a/domain/consensus/model/interface_processes_ghostdagmanager.go b/domain/consensus/model/interface_processes_ghostdagmanager.go index f7cbab390..1222d5565 100644 --- a/domain/consensus/model/interface_processes_ghostdagmanager.go +++ b/domain/consensus/model/interface_processes_ghostdagmanager.go @@ -6,6 +6,6 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" type GHOSTDAGManager interface { GHOSTDAG(blockHash *externalapi.DomainHash) error ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) - Less(blockHashA *externalapi.DomainHash, ghostdagDataA *BlockGHOSTDAGData, - blockHashB *externalapi.DomainHash, ghostdagDataB *BlockGHOSTDAGData) bool + Less(blockHashA *externalapi.DomainHash, ghostdagDataA BlockGHOSTDAGData, + blockHashB *externalapi.DomainHash, ghostdagDataB BlockGHOSTDAGData) bool } diff --git a/domain/consensus/processes/blockbuilder/test_block_builder.go b/domain/consensus/processes/blockbuilder/test_block_builder.go index 967a1e4d4..78e5a56ca 100644 --- a/domain/consensus/processes/blockbuilder/test_block_builder.go +++ b/domain/consensus/processes/blockbuilder/test_block_builder.go @@ -96,13 +96,13 @@ func (bb *testBlockBuilder) buildBlockWithParents(parentHashes []*externalapi.Do return nil, nil, err } - selectedParentStatus, err := bb.testConsensus.ConsensusStateManager().ResolveBlockStatus(ghostdagData.SelectedParent) + selectedParentStatus, err := bb.testConsensus.ConsensusStateManager().ResolveBlockStatus(ghostdagData.SelectedParent()) if err != nil { return nil, nil, err } if selectedParentStatus == externalapi.StatusDisqualifiedFromChain { return nil, nil, errors.Errorf("Error building block with selectedParent %s with status DisqualifiedFromChain", - ghostdagData.SelectedParent) + ghostdagData.SelectedParent()) } pastUTXO, acceptanceData, multiset, err := bb.consensusStateManager.CalculatePastUTXOAndAcceptanceData(tempBlockHash) diff --git a/domain/consensus/processes/blockprocessor/validateandinsertblock.go b/domain/consensus/processes/blockprocessor/validateandinsertblock.go index c5b2de299..b8d8603ec 100644 --- a/domain/consensus/processes/blockprocessor/validateandinsertblock.go +++ b/domain/consensus/processes/blockprocessor/validateandinsertblock.go @@ -170,7 +170,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock) return fmt.Sprintf("Failed to get sync info: %s", err) } return fmt.Sprintf("New virtual's blue score: %d. Sync state: %s. Block count: %d. Header count: %d", - virtualGhostDAGData.BlueScore, syncInfo.State, syncInfo.BlockCount, syncInfo.HeaderCount) + virtualGhostDAGData.BlueScore(), syncInfo.State, syncInfo.BlockCount, syncInfo.HeaderCount) })) if logClosureErr != nil { return logClosureErr diff --git a/domain/consensus/processes/blockvalidator/block_body_in_context.go b/domain/consensus/processes/blockvalidator/block_body_in_context.go index b2897fee2..6e577a6ce 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_context.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_context.go @@ -39,7 +39,7 @@ func (v *blockValidator) checkBlockTransactionsFinalized(blockHash *externalapi. // Ensure all transactions in the block are finalized. for _, tx := range block.Transactions { - if !v.isFinalizedTransaction(tx, ghostdagData.BlueScore, blockTime) { + if !v.isFinalizedTransaction(tx, ghostdagData.BlueScore(), blockTime) { txID := consensushashing.TransactionID(tx) return errors.Wrapf(ruleerrors.ErrUnfinalizedTx, "block contains unfinalized "+ "transaction %s", txID) diff --git a/domain/consensus/processes/blockvalidator/block_header_in_context.go b/domain/consensus/processes/blockvalidator/block_header_in_context.go index 42f5403a6..cc2aa156a 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_context.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_context.go @@ -115,7 +115,7 @@ func (v *blockValidator) checkMergeSizeLimit(hash *externalapi.DomainHash) error return err } - mergeSetSize := len(ghostdagData.MergeSetReds) + len(ghostdagData.MergeSetBlues) + mergeSetSize := len(ghostdagData.MergeSetReds()) + len(ghostdagData.MergeSetBlues()) if uint64(mergeSetSize) > v.mergeSetSizeLimit { return errors.Wrapf(ruleerrors.ErrViolatingMergeLimit, diff --git a/domain/consensus/processes/coinbasemanager/coinbasemanager.go b/domain/consensus/processes/coinbasemanager/coinbasemanager.go index 0799d91b3..068b7fb48 100644 --- a/domain/consensus/processes/coinbasemanager/coinbasemanager.go +++ b/domain/consensus/processes/coinbasemanager/coinbasemanager.go @@ -31,8 +31,8 @@ func (c coinbaseManager) ExpectedCoinbaseTransaction(blockHash *externalapi.Doma return nil, err } - txOuts := make([]*externalapi.DomainTransactionOutput, 0, len(ghostdagData.MergeSetBlues)) - for i, blue := range ghostdagData.MergeSetBlues { + txOuts := make([]*externalapi.DomainTransactionOutput, 0, len(ghostdagData.MergeSetBlues())) + for i, blue := range ghostdagData.MergeSetBlues() { txOut, hasReward, err := c.coinbaseOutputForBlueBlock(blue, acceptanceData[i]) if err != nil { return nil, err @@ -43,7 +43,7 @@ func (c coinbaseManager) ExpectedCoinbaseTransaction(blockHash *externalapi.Doma } } - payload, err := c.serializeCoinbasePayload(ghostdagData.BlueScore, coinbaseData) + payload, err := c.serializeCoinbasePayload(ghostdagData.BlueScore(), coinbaseData) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func (c coinbaseManager) calcBlockSubsidy(blockHash *externalapi.DomainHash) (ui } // Equivalent to: baseSubsidy / 2^(blueScore/subsidyHalvingInterval) - return c.baseSubsidy >> uint(ghostdagData.BlueScore/c.subsidyReductionInterval), nil + return c.baseSubsidy >> uint(ghostdagData.BlueScore()/c.subsidyReductionInterval), nil } // New instantiates a new CoinbaseManager diff --git a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go index 1f60fed01..11b5d63c0 100644 --- a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go +++ b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go @@ -80,8 +80,8 @@ func (csm *consensusStateManager) isNextVirtualSelectedParent(blockHash *externa } log.Tracef("Selecting the next selected parent between "+ - "the block %s the current selected parent %s", blockHash, virtualGhostdagData.SelectedParent) - nextVirtualSelectedParent, err := csm.ghostdagManager.ChooseSelectedParent(virtualGhostdagData.SelectedParent, blockHash) + "the block %s the current selected parent %s", blockHash, virtualGhostdagData.SelectedParent()) + nextVirtualSelectedParent, err := csm.ghostdagManager.ChooseSelectedParent(virtualGhostdagData.SelectedParent(), blockHash) if err != nil { return false, err } diff --git a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go index 4799fd5cc..1e3dbb1c2 100644 --- a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go +++ b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go @@ -30,8 +30,8 @@ func (csm *consensusStateManager) CalculatePastUTXOAndAcceptanceData(blockHash * } log.Tracef("Restoring the past UTXO of block %s with selectedParent %s", - blockHash, blockGHOSTDAGData.SelectedParent) - selectedParentPastUTXO, err := csm.restorePastUTXO(blockGHOSTDAGData.SelectedParent) + blockHash, blockGHOSTDAGData.SelectedParent()) + selectedParentPastUTXO, err := csm.restorePastUTXO(blockGHOSTDAGData.SelectedParent()) if err != nil { return nil, nil, nil, err } @@ -108,13 +108,13 @@ func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainH } func (csm *consensusStateManager) applyBlueBlocks(blockHash *externalapi.DomainHash, - selectedParentPastUTXODiff model.MutableUTXODiff, ghostdagData *model.BlockGHOSTDAGData) ( + selectedParentPastUTXODiff model.MutableUTXODiff, ghostdagData model.BlockGHOSTDAGData) ( model.AcceptanceData, model.MutableUTXODiff, error) { log.Tracef("applyBlueBlocks start for block %s", blockHash) defer log.Tracef("applyBlueBlocks end for block %s", blockHash) - blueBlocks, err := csm.blockStore.Blocks(csm.databaseContext, ghostdagData.MergeSetBlues) + blueBlocks, err := csm.blockStore.Blocks(csm.databaseContext, ghostdagData.MergeSetBlues()) if err != nil { return nil, nil, err } @@ -146,7 +146,7 @@ func (csm *consensusStateManager) applyBlueBlocks(blockHash *externalapi.DomainH transactionID, blueBlockHash) isAccepted, accumulatedMass, err = csm.maybeAcceptTransaction(transaction, blockHash, isSelectedParent, - accumulatedUTXODiff, accumulatedMass, selectedParentMedianTime, ghostdagData.BlueScore) + accumulatedUTXODiff, accumulatedMass, selectedParentMedianTime, ghostdagData.BlueScore()) if err != nil { return nil, nil, err } diff --git a/domain/consensus/processes/consensusstatemanager/multisets.go b/domain/consensus/processes/consensusstatemanager/multisets.go index 7786b4992..bb3f1a91b 100644 --- a/domain/consensus/processes/consensusstatemanager/multisets.go +++ b/domain/consensus/processes/consensusstatemanager/multisets.go @@ -10,22 +10,22 @@ import ( ) func (csm *consensusStateManager) calculateMultiset( - acceptanceData model.AcceptanceData, blockGHOSTDAGData *model.BlockGHOSTDAGData) (model.Multiset, error) { + acceptanceData model.AcceptanceData, blockGHOSTDAGData model.BlockGHOSTDAGData) (model.Multiset, error) { - log.Tracef("calculateMultiset start for block with selected parent %s", blockGHOSTDAGData.SelectedParent) - defer log.Tracef("calculateMultiset end for block with selected parent %s", blockGHOSTDAGData.SelectedParent) + log.Tracef("calculateMultiset start for block with selected parent %s", blockGHOSTDAGData.SelectedParent()) + defer log.Tracef("calculateMultiset end for block with selected parent %s", blockGHOSTDAGData.SelectedParent()) - if blockGHOSTDAGData.SelectedParent == nil { + if blockGHOSTDAGData.SelectedParent() == nil { log.Tracef("Selected parent is nil, which could only happen for the genesis. " + "The genesis, by definition, has an empty multiset") return multiset.New(), nil } - ms, err := csm.multisetStore.Get(csm.databaseContext, blockGHOSTDAGData.SelectedParent) + ms, err := csm.multisetStore.Get(csm.databaseContext, blockGHOSTDAGData.SelectedParent()) if err != nil { return nil, err } - log.Tracef("The multiset for the selected parent %s is: %s", blockGHOSTDAGData.SelectedParent, ms.Hash()) + log.Tracef("The multiset for the selected parent %s is: %s", blockGHOSTDAGData.SelectedParent(), ms.Hash()) for _, blockAcceptanceData := range acceptanceData { for i, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData { @@ -40,7 +40,7 @@ func (csm *consensusStateManager) calculateMultiset( log.Tracef("Is transaction %s a coinbase transaction: %t", transactionID, isCoinbase) var err error - err = addTransactionToMultiset(ms, transaction, blockGHOSTDAGData.BlueScore, isCoinbase) + err = addTransactionToMultiset(ms, transaction, blockGHOSTDAGData.BlueScore(), isCoinbase) if err != nil { return nil, err } diff --git a/domain/consensus/processes/consensusstatemanager/pick_virtual_parents.go b/domain/consensus/processes/consensusstatemanager/pick_virtual_parents.go index bce7a8f6b..84af3bf63 100644 --- a/domain/consensus/processes/consensusstatemanager/pick_virtual_parents.go +++ b/domain/consensus/processes/consensusstatemanager/pick_virtual_parents.go @@ -214,7 +214,7 @@ func (csm *consensusStateManager) boundedMergeBreakingParents( if err != nil { return nil, err } - for _, redBlock := range virtualGHOSTDAGData.MergeSetReds { + for _, redBlock := range virtualGHOSTDAGData.MergeSetReds() { log.Tracef("Check whether red block %s is kosherized", redBlock) isFinalityPointInPast, err := csm.dagTopologyManager.IsAncestorOf(virtualFinalityPoint, redBlock) if err != nil { diff --git a/domain/consensus/processes/consensusstatemanager/resolve_block_status.go b/domain/consensus/processes/consensusstatemanager/resolve_block_status.go index 3a2447aaf..2aa6156b0 100644 --- a/domain/consensus/processes/consensusstatemanager/resolve_block_status.go +++ b/domain/consensus/processes/consensusstatemanager/resolve_block_status.go @@ -79,7 +79,7 @@ func (csm *consensusStateManager) findSelectedParentStatus(unverifiedBlocks []*e if err != nil { return 0, err } - return csm.blockStatusStore.Get(csm.databaseContext, lastUnverifiedBlockGHOSTDAGData.SelectedParent) + return csm.blockStatusStore.Get(csm.databaseContext, lastUnverifiedBlockGHOSTDAGData.SelectedParent()) } func (csm *consensusStateManager) getUnverifiedChainBlocks( @@ -110,13 +110,13 @@ func (csm *consensusStateManager) getUnverifiedChainBlocks( return nil, err } - if currentBlockGHOSTDAGData.SelectedParent == nil { + if currentBlockGHOSTDAGData.SelectedParent() == nil { log.Tracef("Genesis block reached. Returning all the "+ "unverified blocks prior to it: %s", unverifiedBlocks) return unverifiedBlocks, nil } - currentHash = currentBlockGHOSTDAGData.SelectedParent + currentHash = currentBlockGHOSTDAGData.SelectedParent() } } diff --git a/domain/consensus/processes/dagtraversalmanager/block_heap.go b/domain/consensus/processes/dagtraversalmanager/block_heap.go index 6a1caaadd..40a0849ed 100644 --- a/domain/consensus/processes/dagtraversalmanager/block_heap.go +++ b/domain/consensus/processes/dagtraversalmanager/block_heap.go @@ -9,7 +9,7 @@ import ( type blockHeapNode struct { hash *externalapi.DomainHash - ghostdagData *model.BlockGHOSTDAGData + ghostdagData model.BlockGHOSTDAGData } // baseHeap is an implementation for heap.Interface that sorts blocks by their height diff --git a/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go b/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go index bc157f78d..5a0329fe3 100644 --- a/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go +++ b/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go @@ -32,7 +32,7 @@ func (spi *selectedParentIterator) Next() bool { if err != nil { panic(fmt.Sprintf("ghostdagDataStore is missing ghostdagData for: %v. '%s' ", spi.current, err)) } - spi.current = ghostdagData.SelectedParent + spi.current = ghostdagData.SelectedParent() return spi.current != nil } @@ -75,17 +75,17 @@ func (dtm *dagTraversalManager) BlockAtDepth(highHash *externalapi.DomainHash, d } requiredBlueScore := uint64(0) - if highBlockGHOSTDAGData.BlueScore > depth { - requiredBlueScore = highBlockGHOSTDAGData.BlueScore - depth + if highBlockGHOSTDAGData.BlueScore() > depth { + requiredBlueScore = highBlockGHOSTDAGData.BlueScore() - depth } currentBlockGHOSTDAGData := highBlockGHOSTDAGData // If we used `BlockIterator` we'd need to do more calls to `ghostdagDataStore` so we can get the blueScore - for currentBlockGHOSTDAGData.BlueScore >= requiredBlueScore { - if currentBlockGHOSTDAGData.SelectedParent == nil { // genesis + for currentBlockGHOSTDAGData.BlueScore() >= requiredBlueScore { + if currentBlockGHOSTDAGData.SelectedParent() == nil { // genesis return currentBlockHash, nil } - currentBlockHash = currentBlockGHOSTDAGData.SelectedParent + currentBlockHash = currentBlockGHOSTDAGData.SelectedParent() currentBlockGHOSTDAGData, err = dtm.ghostdagDataStore.Get(dtm.databaseContext, currentBlockHash) if err != nil { return nil, err @@ -104,15 +104,15 @@ func (dtm *dagTraversalManager) LowestChainBlockAboveOrEqualToBlueScore(highHash currentBlockGHOSTDAGData := highBlockGHOSTDAGData iterator := dtm.SelectedParentIterator(highHash) for iterator.Next() { - selectedParentBlockGHOSTDAGData, err := dtm.ghostdagDataStore.Get(dtm.databaseContext, currentBlockGHOSTDAGData.SelectedParent) + selectedParentBlockGHOSTDAGData, err := dtm.ghostdagDataStore.Get(dtm.databaseContext, currentBlockGHOSTDAGData.SelectedParent()) if err != nil { return nil, err } - if selectedParentBlockGHOSTDAGData.BlueScore < blueScore { + if selectedParentBlockGHOSTDAGData.BlueScore() < blueScore { break } - currentHash = selectedParentBlockGHOSTDAGData.SelectedParent + currentHash = selectedParentBlockGHOSTDAGData.SelectedParent() currentBlockGHOSTDAGData = selectedParentBlockGHOSTDAGData } diff --git a/domain/consensus/processes/dagtraversalmanager/window.go b/domain/consensus/processes/dagtraversalmanager/window.go index 8f4805984..25b8a3211 100644 --- a/domain/consensus/processes/dagtraversalmanager/window.go +++ b/domain/consensus/processes/dagtraversalmanager/window.go @@ -15,15 +15,15 @@ func (dtm *dagTraversalManager) BlueWindow(startingBlock *externalapi.DomainHash return nil, err } - for uint64(len(window)) < windowSize && currentGHOSTDAGData.SelectedParent != nil { - for _, blue := range currentGHOSTDAGData.MergeSetBlues { + for uint64(len(window)) < windowSize && currentGHOSTDAGData.SelectedParent() != nil { + for _, blue := range currentGHOSTDAGData.MergeSetBlues() { window = append(window, blue) if uint64(len(window)) == windowSize { break } } - currentHash = currentGHOSTDAGData.SelectedParent + currentHash = currentGHOSTDAGData.SelectedParent() currentGHOSTDAGData, err = dtm.ghostdagDataStore.Get(dtm.databaseContext, currentHash) if err != nil { return nil, err diff --git a/domain/consensus/processes/difficultymanager/difficultymanager.go b/domain/consensus/processes/difficultymanager/difficultymanager.go index 45bbadd1a..7a18faad6 100644 --- a/domain/consensus/processes/difficultymanager/difficultymanager.go +++ b/domain/consensus/processes/difficultymanager/difficultymanager.go @@ -1,12 +1,13 @@ package difficultymanager import ( + "math/big" + "time" + "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/util" "github.com/kaspanet/kaspad/util/bigintpool" - "math/big" - "time" ) // DifficultyManager provides a method to resolve the @@ -94,7 +95,7 @@ func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHas } // Not enough blocks for building a difficulty window. - if bluestGhostDAG.BlueScore < dm.difficultyAdjustmentWindowSize+1 { + if bluestGhostDAG.BlueScore() < dm.difficultyAdjustmentWindowSize+1 { return dm.genesisBits() } diff --git a/domain/consensus/processes/difficultymanager/difficultymanager_test.go b/domain/consensus/processes/difficultymanager/difficultymanager_test.go new file mode 100644 index 000000000..8b8de6df3 --- /dev/null +++ b/domain/consensus/processes/difficultymanager/difficultymanager_test.go @@ -0,0 +1,203 @@ +package difficultymanager_test + +import ( + "testing" + + "github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing" + + "github.com/kaspanet/kaspad/domain/consensus" + "github.com/kaspanet/kaspad/domain/consensus/model" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/utils/testutils" + "github.com/kaspanet/kaspad/domain/dagconfig" + "github.com/kaspanet/kaspad/util" +) + +func TestDifficulty(t *testing.T) { + testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) { + params.K = 1 + params.DifficultyAdjustmentWindowSize = 264 + + factory := consensus.NewFactory() + tc, teardown, err := factory.NewTestConsensus(params, "TestDifficulty") + if err != nil { + t.Fatalf("Error setting up consensus: %+v", err) + } + defer teardown() + + addBlock := func(blockTime int64, parents ...*externalapi.DomainHash) (*externalapi.DomainBlock, *externalapi.DomainHash) { + bluestParent, err := tc.GHOSTDAGManager().ChooseSelectedParent(parents...) + if err != nil { + t.Fatalf("ChooseSelectedParent: %+v", err) + } + + if blockTime == 0 { + header, err := tc.BlockHeaderStore().BlockHeader(tc.DatabaseContext(), bluestParent) + if err != nil { + t.Fatalf("BlockHeader: %+v", err) + } + + blockTime = header.TimeInMilliseconds + params.TargetTimePerBlock.Milliseconds() + } + + block, _, err := tc.BuildBlockWithParents(parents, nil, nil) + if err != nil { + t.Fatalf("BuildBlockWithParents: %+v", err) + } + + block.Header.TimeInMilliseconds = blockTime + err = tc.ValidateAndInsertBlock(block) + if err != nil { + t.Fatalf("ValidateAndInsertBlock: %+v", err) + } + + return block, consensushashing.BlockHash(block) + } + + minimumTime := func(parents ...*externalapi.DomainHash) int64 { + var tempHash externalapi.DomainHash + tc.BlockRelationStore().StageBlockRelation(&tempHash, &model.BlockRelations{ + Parents: parents, + Children: nil, + }) + defer tc.BlockRelationStore().Discard() + + err = tc.GHOSTDAGManager().GHOSTDAG(&tempHash) + if err != nil { + t.Fatalf("GHOSTDAG: %+v", err) + } + defer tc.GHOSTDAGDataStore().Discard() + + pastMedianTime, err := tc.PastMedianTimeManager().PastMedianTime(&tempHash) + if err != nil { + t.Fatalf("PastMedianTime: %+v", err) + } + + return pastMedianTime + 1 + } + + addBlockWithMinimumTime := func(parents ...*externalapi.DomainHash) (*externalapi.DomainBlock, *externalapi.DomainHash) { + minTime := minimumTime(parents...) + return addBlock(minTime, parents...) + } + + tipHash := params.GenesisHash + tip := params.GenesisBlock + for i := uint64(0); i < params.DifficultyAdjustmentWindowSize; i++ { + tip, tipHash = addBlock(0, tipHash) + if tip.Header.Bits != params.GenesisBlock.Header.Bits { + t.Fatalf("As long as the bluest parent's blue score is less then the difficulty adjustment " + + "window size, the difficulty should be the same as genesis'") + } + } + for i := uint64(0); i < params.DifficultyAdjustmentWindowSize+100; i++ { + tip, tipHash = addBlock(0, tipHash) + if tip.Header.Bits != params.GenesisBlock.Header.Bits { + t.Fatalf("As long as the block rate remains the same, the difficulty shouldn't change") + } + } + + blockInThePast, tipHash := addBlockWithMinimumTime(tipHash) + if blockInThePast.Header.Bits != tip.Header.Bits { + t.Fatalf("The difficulty should only change when blockInThePast is in the past of a block bluest parent") + } + tip = blockInThePast + + tip, tipHash = addBlock(0, tipHash) + if tip.Header.Bits != blockInThePast.Header.Bits { + t.Fatalf("The difficulty should only change when blockInThePast is in the past of a block bluest parent") + } + + tip, tipHash = addBlock(0, tipHash) + if compareBits(tip.Header.Bits, blockInThePast.Header.Bits) >= 0 { + t.Fatalf("tip.bits should be smaller than blockInThePast.bits because blockInThePast increased the " + + "block rate, so the difficulty should increase as well") + } + + var expectedBits uint32 + switch params.Name { + case "kaspa-testnet", "kaspa-devnet": + expectedBits = uint32(0x1e7f83df) + case "kaspa-mainnet", "kaspa-simnet": + expectedBits = uint32(0x207f83df) + } + + if tip.Header.Bits != expectedBits { + t.Errorf("tip.bits was expected to be %x but got %x", expectedBits, tip.Header.Bits) + } + + // Increase block rate to increase difficulty + for i := uint64(0); i < params.DifficultyAdjustmentWindowSize; i++ { + tip, tipHash = addBlockWithMinimumTime(tipHash) + tipGHOSTDAGData, err := tc.GHOSTDAGDataStore().Get(tc.DatabaseContext(), tipHash) + if err != nil { + t.Fatalf("GHOSTDAGDataStore: %+v", err) + } + + selectedParentHeader, err := tc.BlockHeaderStore().BlockHeader(tc.DatabaseContext(), + tipGHOSTDAGData.SelectedParent()) + if err != nil { + t.Fatalf("BlockHeader: %+v", err) + } + + if compareBits(tip.Header.Bits, selectedParentHeader.Bits) > 0 { + t.Fatalf("Because we're increasing the block rate, the difficulty can't decrease") + } + } + + // Add blocks until difficulty stabilizes + lastBits := tip.Header.Bits + sameBitsCount := uint64(0) + for sameBitsCount < params.DifficultyAdjustmentWindowSize+1 { + tip, tipHash = addBlock(0, tipHash) + if tip.Header.Bits == lastBits { + sameBitsCount++ + } else { + lastBits = tip.Header.Bits + sameBitsCount = 0 + } + } + + slowBlockTime := tip.Header.TimeInMilliseconds + params.TargetTimePerBlock.Milliseconds() + 1000 + slowBlock, tipHash := addBlock(slowBlockTime, tipHash) + if slowBlock.Header.Bits != tip.Header.Bits { + t.Fatalf("The difficulty should only change when slowBlock is in the past of a block bluest parent") + } + + tip = slowBlock + + tip, tipHash = addBlock(0, tipHash) + if tip.Header.Bits != slowBlock.Header.Bits { + t.Fatalf("The difficulty should only change when slowBlock is in the past of a block bluest parent") + } + tip, tipHash = addBlock(0, tipHash) + if compareBits(tip.Header.Bits, slowBlock.Header.Bits) <= 0 { + t.Fatalf("tip.bits should be smaller than slowBlock.bits because slowBlock decreased the block" + + " rate, so the difficulty should decrease as well") + } + + _, tipHash = addBlock(0, tipHash) + splitBlockHash := tipHash + for i := 0; i < 100; i++ { + _, tipHash = addBlock(0, tipHash) + } + blueTipHash := tipHash + + redChainTipHash := splitBlockHash + for i := 0; i < 10; i++ { + _, redChainTipHash = addBlockWithMinimumTime(redChainTipHash) + } + tipWithRedPast, _ := addBlock(0, redChainTipHash, blueTipHash) + tipWithoutRedPast, _ := addBlock(0, blueTipHash) + if tipWithoutRedPast.Header.Bits != tipWithRedPast.Header.Bits { + t.Fatalf("tipWithoutRedPast.bits should be the same as tipWithRedPast.bits because red blocks" + + " shouldn't affect the difficulty") + } + }) +} + +func compareBits(a uint32, b uint32) int { + aTarget := util.CompactToBig(a) + bTarget := util.CompactToBig(b) + return aTarget.Cmp(bTarget) +} diff --git a/domain/consensus/processes/ghostdag2/ghostdagimpl.go b/domain/consensus/processes/ghostdag2/ghostdagimpl.go index 867f52a8e..abaaf183e 100644 --- a/domain/consensus/processes/ghostdag2/ghostdagimpl.go +++ b/domain/consensus/processes/ghostdag2/ghostdagimpl.go @@ -1,9 +1,12 @@ package ghostdag2 import ( + "sort" + + "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager" + "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" - "sort" ) type ghostdagHelper struct { @@ -44,7 +47,7 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error if err != nil { return err } - blockScore := blockData.BlueScore + blockScore := blockData.BlueScore() if blockScore > maxNum { selectedParent = parent maxNum = blockScore @@ -91,13 +94,8 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error } myScore += uint64(len(mergeSetBlues)) - e := model.BlockGHOSTDAGData{ - BlueScore: myScore, - SelectedParent: selectedParent, - MergeSetBlues: mergeSetBlues, - MergeSetReds: mergeSetReds, - } - gh.dataStore.Stage(blockCandidate, &e) + e := ghostdagmanager.NewBlockGHOSTDAGData(myScore, selectedParent, mergeSetBlues, mergeSetReds, nil) + gh.dataStore.Stage(blockCandidate, e) return nil } @@ -220,7 +218,7 @@ func (gh *ghostdagHelper) validateKCluster(chain *externalapi.DomainHash, checke if err != nil { return false, err } - if mergeSetReds := dataStore.MergeSetReds; contains(checkedBlock, mergeSetReds) { + if mergeSetReds := dataStore.MergeSetReds(); contains(checkedBlock, mergeSetReds) { return false, nil } } else { @@ -326,14 +324,14 @@ func (gh *ghostdagHelper) findBlueSet(blueSet *[]*externalapi.DomainHash, select if err != nil { return err } - mergeSetBlue := blockData.MergeSetBlues + mergeSetBlue := blockData.MergeSetBlues() for _, blue := range mergeSetBlue { if contains(blue, *blueSet) { continue } *blueSet = append(*blueSet, blue) } - selectedParent = blockData.SelectedParent + selectedParent = blockData.SelectedParent() } return nil } @@ -356,10 +354,10 @@ func (gh *ghostdagHelper) sortByBlueScore(arr []*externalapi.DomainHash) error { return false } - if blockLeft.BlueScore < blockRight.BlueScore { + if blockLeft.BlueScore() < blockRight.BlueScore() { return true } - if blockLeft.BlueScore == blockRight.BlueScore { + if blockLeft.BlueScore() == blockRight.BlueScore() { return ismoreHash(arr[j], arr[i]) } return false @@ -369,13 +367,13 @@ func (gh *ghostdagHelper) sortByBlueScore(arr []*externalapi.DomainHash) error { /* --------------------------------------------- */ -func (gh *ghostdagHelper) BlockData(blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) { +func (gh *ghostdagHelper) BlockData(blockHash *externalapi.DomainHash) (model.BlockGHOSTDAGData, error) { return gh.dataStore.Get(gh.dbAccess, blockHash) } func (gh *ghostdagHelper) ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) { panic("implement me") } -func (gh *ghostdagHelper) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *model.BlockGHOSTDAGData, blockHashB *externalapi.DomainHash, ghostdagDataB *model.BlockGHOSTDAGData) bool { +func (gh *ghostdagHelper) Less(blockHashA *externalapi.DomainHash, ghostdagDataA model.BlockGHOSTDAGData, blockHashB *externalapi.DomainHash, ghostdagDataB model.BlockGHOSTDAGData) bool { panic("implement me") } diff --git a/domain/consensus/processes/ghostdagmanager/compare.go b/domain/consensus/processes/ghostdagmanager/compare.go index b5c16f27e..76ad1844a 100644 --- a/domain/consensus/processes/ghostdagmanager/compare.go +++ b/domain/consensus/processes/ghostdagmanager/compare.go @@ -53,11 +53,11 @@ func (gm *ghostdagManager) ChooseSelectedParent(blockHashes ...*externalapi.Doma return selectedParent, nil } -func (gm *ghostdagManager) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *model.BlockGHOSTDAGData, - blockHashB *externalapi.DomainHash, ghostdagDataB *model.BlockGHOSTDAGData) bool { +func (gm *ghostdagManager) Less(blockHashA *externalapi.DomainHash, ghostdagDataA model.BlockGHOSTDAGData, + blockHashB *externalapi.DomainHash, ghostdagDataB model.BlockGHOSTDAGData) bool { - blockBlueScoreA := ghostdagDataA.BlueScore - blockBlueScoreB := ghostdagDataB.BlueScore + blockBlueScoreA := ghostdagDataA.BlueScore() + blockBlueScoreB := ghostdagDataB.BlueScore() if blockBlueScoreA == blockBlueScoreB { return hashes.Less(blockHashA, blockHashB) } diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag.go b/domain/consensus/processes/ghostdagmanager/ghostdag.go index c510959a5..8e24ea4c1 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdag.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdag.go @@ -25,10 +25,10 @@ import ( // // For further details see the article https://eprint.iacr.org/2018/104.pdf func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error { - newBlockData := &model.BlockGHOSTDAGData{ - MergeSetBlues: make([]*externalapi.DomainHash, 0), - MergeSetReds: make([]*externalapi.DomainHash, 0), - BluesAnticoneSizes: make(map[externalapi.DomainHash]model.KType), + newBlockData := &blockGHOSTDAGData{ + mergeSetBlues: make([]*externalapi.DomainHash, 0), + mergeSetReds: make([]*externalapi.DomainHash, 0), + bluesAnticoneSizes: make(map[externalapi.DomainHash]model.KType), } blockParents, err := gm.dagTopologyManager.Parents(blockHash) @@ -43,12 +43,12 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error { return err } - newBlockData.SelectedParent = selectedParent - newBlockData.MergeSetBlues = append(newBlockData.MergeSetBlues, selectedParent) - newBlockData.BluesAnticoneSizes[*selectedParent] = 0 + newBlockData.selectedParent = selectedParent + newBlockData.mergeSetBlues = append(newBlockData.mergeSetBlues, selectedParent) + newBlockData.bluesAnticoneSizes[*selectedParent] = 0 } - mergeSetWithoutSelectedParent, err := gm.mergeSetWithoutSelectedParent(newBlockData.SelectedParent, blockParents) + mergeSetWithoutSelectedParent, err := gm.mergeSetWithoutSelectedParent(newBlockData.selectedParent, blockParents) if err != nil { return err } @@ -61,25 +61,25 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error { if isBlue { // No k-cluster violation found, we can now set the candidate block as blue - newBlockData.MergeSetBlues = append(newBlockData.MergeSetBlues, blueCandidate) - newBlockData.BluesAnticoneSizes[*blueCandidate] = candidateAnticoneSize + newBlockData.mergeSetBlues = append(newBlockData.mergeSetBlues, blueCandidate) + newBlockData.bluesAnticoneSizes[*blueCandidate] = candidateAnticoneSize for blue, blueAnticoneSize := range candidateBluesAnticoneSizes { - newBlockData.BluesAnticoneSizes[blue] = blueAnticoneSize + 1 + newBlockData.bluesAnticoneSizes[blue] = blueAnticoneSize + 1 } } else { - newBlockData.MergeSetReds = append(newBlockData.MergeSetReds, blueCandidate) + newBlockData.mergeSetReds = append(newBlockData.mergeSetReds, blueCandidate) } } if !isGenesis { - selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.SelectedParent) + selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.selectedParent) if err != nil { return err } - newBlockData.BlueScore = selectedParentGHOSTDAGData.BlueScore + uint64(len(newBlockData.MergeSetBlues)) + newBlockData.blueScore = selectedParentGHOSTDAGData.BlueScore() + uint64(len(newBlockData.mergeSetBlues)) } else { // Genesis's blue score is defined to be 0. - newBlockData.BlueScore = 0 + newBlockData.blueScore = 0 } gm.ghostdagDataStore.Stage(blockHash, newBlockData) @@ -89,15 +89,15 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error { type chainBlockData struct { hash *externalapi.DomainHash - blockData *model.BlockGHOSTDAGData + blockData model.BlockGHOSTDAGData } -func (gm *ghostdagManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGData, blueCandidate *externalapi.DomainHash) ( +func (gm *ghostdagManager) checkBlueCandidate(newBlockData *blockGHOSTDAGData, blueCandidate *externalapi.DomainHash) ( isBlue bool, candidateAnticoneSize model.KType, candidateBluesAnticoneSizes map[externalapi.DomainHash]model.KType, err error) { // The maximum length of node.blues can be K+1 because // it contains the selected parent. - if model.KType(len(newBlockData.MergeSetBlues)) == gm.k+1 { + if model.KType(len(newBlockData.mergeSetBlues)) == gm.k+1 { return false, 0, nil, nil } @@ -126,12 +126,12 @@ func (gm *ghostdagManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGD return false, 0, nil, nil } - selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, chainBlock.blockData.SelectedParent) + selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, chainBlock.blockData.SelectedParent()) if err != nil { return false, 0, nil, err } - chainBlock = chainBlockData{hash: chainBlock.blockData.SelectedParent, + chainBlock = chainBlockData{hash: chainBlock.blockData.SelectedParent(), blockData: selectedParentGHOSTDAGData, } } @@ -139,7 +139,7 @@ func (gm *ghostdagManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGD return true, candidateAnticoneSize, candidateBluesAnticoneSizes, nil } -func (gm *ghostdagManager) checkBlueCandidateWithChainBlock(newBlockData *model.BlockGHOSTDAGData, +func (gm *ghostdagManager) checkBlueCandidateWithChainBlock(newBlockData model.BlockGHOSTDAGData, chainBlock chainBlockData, blueCandidate *externalapi.DomainHash, candidateBluesAnticoneSizes map[externalapi.DomainHash]model.KType, candidateAnticoneSize *model.KType) (isBlue, isRed bool, err error) { @@ -164,7 +164,7 @@ func (gm *ghostdagManager) checkBlueCandidateWithChainBlock(newBlockData *model. } } - for _, block := range chainBlock.blockData.MergeSetBlues { + for _, block := range chainBlock.blockData.MergeSetBlues() { // Skip blocks that exist in the past of blueCandidate. isAncestorOfBlueCandidate, err := gm.dagTopologyManager.IsAncestorOf(block, blueCandidate) if err != nil { @@ -204,16 +204,16 @@ func (gm *ghostdagManager) checkBlueCandidateWithChainBlock(newBlockData *model. // blueAnticoneSize returns the blue anticone size of 'block' from the worldview of 'context'. // Expects 'block' to be in the blue set of 'context' -func (gm *ghostdagManager) blueAnticoneSize(block *externalapi.DomainHash, context *model.BlockGHOSTDAGData) (model.KType, error) { +func (gm *ghostdagManager) blueAnticoneSize(block *externalapi.DomainHash, context model.BlockGHOSTDAGData) (model.KType, error) { for current := context; current != nil; { - if blueAnticoneSize, ok := current.BluesAnticoneSizes[*block]; ok { + if blueAnticoneSize, ok := current.BluesAnticoneSizes()[*block]; ok { return blueAnticoneSize, nil } - if current.SelectedParent == nil { + if current.SelectedParent() == nil { break } var err error - current, err = gm.ghostdagDataStore.Get(gm.databaseContext, current.SelectedParent) + current, err = gm.ghostdagDataStore.Get(gm.databaseContext, current.SelectedParent()) if err != nil { return 0, err } diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag_data.go b/domain/consensus/processes/ghostdagmanager/ghostdag_data.go new file mode 100644 index 000000000..b708241be --- /dev/null +++ b/domain/consensus/processes/ghostdagmanager/ghostdag_data.go @@ -0,0 +1,51 @@ +package ghostdagmanager + +import ( + "github.com/kaspanet/kaspad/domain/consensus/model" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" +) + +type blockGHOSTDAGData struct { + blueScore uint64 + selectedParent *externalapi.DomainHash + mergeSetBlues []*externalapi.DomainHash + mergeSetReds []*externalapi.DomainHash + bluesAnticoneSizes map[externalapi.DomainHash]model.KType +} + +// NewBlockGHOSTDAGData creates a new instance of model.BlockGHOSTDAGData +func NewBlockGHOSTDAGData( + blueScore uint64, + selectedParent *externalapi.DomainHash, + mergeSetBlues []*externalapi.DomainHash, + mergeSetReds []*externalapi.DomainHash, + bluesAnticoneSizes map[externalapi.DomainHash]model.KType) model.BlockGHOSTDAGData { + + return &blockGHOSTDAGData{ + blueScore: blueScore, + selectedParent: selectedParent, + mergeSetBlues: mergeSetBlues, + mergeSetReds: mergeSetReds, + bluesAnticoneSizes: bluesAnticoneSizes, + } +} + +func (bgd *blockGHOSTDAGData) BlueScore() uint64 { + return bgd.blueScore +} + +func (bgd *blockGHOSTDAGData) SelectedParent() *externalapi.DomainHash { + return bgd.selectedParent +} + +func (bgd *blockGHOSTDAGData) MergeSetBlues() []*externalapi.DomainHash { + return bgd.mergeSetBlues +} + +func (bgd *blockGHOSTDAGData) MergeSetReds() []*externalapi.DomainHash { + return bgd.mergeSetReds +} + +func (bgd *blockGHOSTDAGData) BluesAnticoneSizes() map[externalapi.DomainHash]model.KType { + return bgd.bluesAnticoneSizes +} diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go index bd01b100e..6afcf6091 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go @@ -1,14 +1,17 @@ -package ghostdagmanager +package ghostdagmanager_test import ( "encoding/json" - "github.com/kaspanet/kaspad/domain/consensus/model" - "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" - "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdag2" "os" "path/filepath" "reflect" "testing" + + "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager" + + "github.com/kaspanet/kaspad/domain/consensus/model" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdag2" ) // TestGHOSTDAG iterates over several dag simulations, and checks @@ -47,15 +50,9 @@ func TestGHOSTDAG(t *testing.T) { } ghostdagDataStore := &GHOSTDAGDataStoreImpl{ - dagMap: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData), - } - var blockGHOSTDAGDataGenesis = &model.BlockGHOSTDAGData{ - BlueScore: 0, - SelectedParent: nil, - MergeSetBlues: nil, - MergeSetReds: nil, - BluesAnticoneSizes: nil, + dagMap: make(map[externalapi.DomainHash]model.BlockGHOSTDAGData), } + blockGHOSTDAGDataGenesis := ghostdagmanager.NewBlockGHOSTDAGData(0, nil, nil, nil, nil) var testsCounter int err := filepath.Walk("../../testdata/dags", func(path string, info os.FileInfo, err error) error { @@ -87,7 +84,7 @@ func TestGHOSTDAG(t *testing.T) { //NOTE: FOR ADDING/REMOVING AN IMPLEMENTATION CHANGE BELOW: implementationFactories := []implManager{ - {New, "Original"}, + {ghostdagmanager.New, "Original"}, {ghostdag2.New, "Tal's impl"}, } @@ -110,30 +107,30 @@ func TestGHOSTDAG(t *testing.T) { factory.implName, info.Name(), testBlockData.ID, err) } - if testBlockData.Score != (ghostdagData.BlueScore) { + if testBlockData.Score != (ghostdagData.BlueScore()) { t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected blue score %d but got %d.", - factory.implName, info.Name(), testBlockData.ID, testBlockData.Score, ghostdagData.BlueScore) + factory.implName, info.Name(), testBlockData.ID, testBlockData.Score, ghostdagData.BlueScore()) } - if *StringToByte(testBlockData.SelectedParent) != *ghostdagData.SelectedParent { + if *StringToByte(testBlockData.SelectedParent) != *ghostdagData.SelectedParent() { t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected selected parent %v but got %v.", - factory.implName, info.Name(), testBlockData.ID, testBlockData.SelectedParent, string(ghostdagData.SelectedParent[:])) + factory.implName, info.Name(), testBlockData.ID, testBlockData.SelectedParent, ghostdagData.SelectedParent()) } - if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues) { + if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues()) { t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set blues %v but got %v.", - factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetBlues, hashesToStrings(ghostdagData.MergeSetBlues)) + factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetBlues, hashesToStrings(ghostdagData.MergeSetBlues())) } - if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetReds), ghostdagData.MergeSetReds) { + if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetReds), ghostdagData.MergeSetReds()) { t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set reds %v but got %v.", - factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetReds, hashesToStrings(ghostdagData.MergeSetReds)) + factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetReds, hashesToStrings(ghostdagData.MergeSetReds())) } } dagTopology.parentsMap = make(map[externalapi.DomainHash][]*externalapi.DomainHash) dagTopology.parentsMap[genesisHash] = nil - ghostdagDataStore.dagMap = make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData) + ghostdagDataStore.dagMap = make(map[externalapi.DomainHash]model.BlockGHOSTDAGData) ghostdagDataStore.dagMap[genesisHash] = blockGHOSTDAGDataGenesis } @@ -172,10 +169,10 @@ func StringToByteArray(stringIDArr []string) []*externalapi.DomainHash { /* ---------------------- */ type GHOSTDAGDataStoreImpl struct { - dagMap map[externalapi.DomainHash]*model.BlockGHOSTDAGData + dagMap map[externalapi.DomainHash]model.BlockGHOSTDAGData } -func (ds *GHOSTDAGDataStoreImpl) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) { +func (ds *GHOSTDAGDataStoreImpl) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData model.BlockGHOSTDAGData) { ds.dagMap[*blockHash] = blockGHOSTDAGData } @@ -191,7 +188,7 @@ func (ds *GHOSTDAGDataStoreImpl) Commit(dbTx model.DBTransaction) error { panic("implement me") } -func (ds *GHOSTDAGDataStoreImpl) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) { +func (ds *GHOSTDAGDataStoreImpl) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (model.BlockGHOSTDAGData, error) { v, ok := ds.dagMap[*blockHash] if ok { return v, nil diff --git a/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go b/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go index cbf29f331..155dcd731 100644 --- a/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go +++ b/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go @@ -46,7 +46,7 @@ func (mdm *mergeDepthManager) CheckBoundedMergeDepth(blockHash *externalapi.Doma } // Return nil on genesis - if ghostdagData.SelectedParent == nil { + if ghostdagData.SelectedParent() == nil { return nil } @@ -55,7 +55,7 @@ func (mdm *mergeDepthManager) CheckBoundedMergeDepth(blockHash *externalapi.Doma return err } - for _, red := range ghostdagData.MergeSetReds { + for _, red := range ghostdagData.MergeSetReds() { doesRedHaveFinalityPointInPast, err := mdm.dagTopologyManager.IsAncestorOf(finalityPoint, red) if err != nil { return err @@ -85,9 +85,9 @@ func (mdm mergeDepthManager) NonBoundedMergeDepthViolatingBlues(blockHash *exter return nil, err } - nonBoundedMergeDepthViolatingBlues := make([]*externalapi.DomainHash, 0, len(ghostdagData.MergeSetBlues)) + nonBoundedMergeDepthViolatingBlues := make([]*externalapi.DomainHash, 0, len(ghostdagData.MergeSetBlues())) - for _, blue := range ghostdagData.MergeSetBlues { + for _, blue := range ghostdagData.MergeSetBlues() { notViolatingFinality, err := mdm.hasFinalityPointInOthersSelectedChain(blockHash, blue) if err != nil { return nil, err diff --git a/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go index a2d92dbbb..5d29206ce 100644 --- a/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go +++ b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go @@ -1,10 +1,11 @@ package pastmediantimemanager import ( + "sort" + "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/pkg/errors" - "sort" ) // pastMedianTimeManager provides a method to resolve the @@ -44,7 +45,7 @@ func (pmtm *pastMedianTimeManager) PastMedianTime(blockHash *externalapi.DomainH if err != nil { return 0, err } - selectedParentHash := blockGHOSTDAGData.SelectedParent + selectedParentHash := blockGHOSTDAGData.SelectedParent() // Genesis block if selectedParentHash == nil { diff --git a/domain/consensus/processes/pruningmanager/pruningmanager.go b/domain/consensus/processes/pruningmanager/pruningmanager.go index 9dda97c9d..57ca1dd12 100644 --- a/domain/consensus/processes/pruningmanager/pruningmanager.go +++ b/domain/consensus/processes/pruningmanager/pruningmanager.go @@ -99,14 +99,14 @@ func (pm *pruningManager) FindNextPruningPoint() error { if err != nil { return err } - currentPBlueScore := currentPGhost.BlueScore + currentPBlueScore := currentPGhost.BlueScore() // Because the pruning point changes only once per finality, then there's no need to even check for that if a finality interval hasn't passed. - if virtual.BlueScore <= currentPBlueScore+pm.finalityInterval { + if virtual.BlueScore() <= currentPBlueScore+pm.finalityInterval { return nil } // This means the pruning point is still genesis. - if virtual.BlueScore <= pm.pruningDepth+pm.finalityInterval { + if virtual.BlueScore() <= pm.pruningDepth+pm.finalityInterval { return nil } @@ -121,7 +121,7 @@ func (pm *pruningManager) FindNextPruningPoint() error { } // Actually check if the pruning point changed - if (currentPBlueScore / pm.finalityInterval) < (candidatePGhost.BlueScore / pm.finalityInterval) { + if (currentPBlueScore / pm.finalityInterval) < (candidatePGhost.BlueScore() / pm.finalityInterval) { err = pm.savePruningPoint(candidatePHash) if err != nil { return err diff --git a/domain/consensus/processes/reachabilitymanager/reachabilitymanager.go b/domain/consensus/processes/reachabilitymanager/reachabilitymanager.go index 9bafb96c4..577239571 100644 --- a/domain/consensus/processes/reachabilitymanager/reachabilitymanager.go +++ b/domain/consensus/processes/reachabilitymanager/reachabilitymanager.go @@ -45,7 +45,7 @@ func (rt *reachabilityManager) AddBlock(blockHash *externalapi.DomainHash) error } // If this is the genesis node, simply initialize it and return - if ghostdagData.SelectedParent == nil { + if ghostdagData.SelectedParent() == nil { rt.stageReindexRoot(blockHash) return nil } @@ -56,16 +56,16 @@ func (rt *reachabilityManager) AddBlock(blockHash *externalapi.DomainHash) error } // Insert the node into the selected parent's reachability tree - err = rt.addChild(ghostdagData.SelectedParent, blockHash, reindexRoot) + err = rt.addChild(ghostdagData.SelectedParent(), blockHash, reindexRoot) if err != nil { return err } // Add the block to the futureCoveringSets of all the blocks // in the merget set - mergeSet := make([]*externalapi.DomainHash, len(ghostdagData.MergeSetBlues)+len(ghostdagData.MergeSetReds)) - copy(mergeSet, ghostdagData.MergeSetBlues) - copy(mergeSet[len(ghostdagData.MergeSetBlues):], ghostdagData.MergeSetReds) + mergeSet := make([]*externalapi.DomainHash, len(ghostdagData.MergeSetBlues())+len(ghostdagData.MergeSetReds())) + copy(mergeSet, ghostdagData.MergeSetBlues()) + copy(mergeSet[len(ghostdagData.MergeSetBlues()):], ghostdagData.MergeSetReds()) for _, current := range mergeSet { err = rt.insertToFutureCoveringSet(current, blockHash) diff --git a/domain/consensus/processes/reachabilitymanager/tree.go b/domain/consensus/processes/reachabilitymanager/tree.go index 8ea711939..1dea962ea 100644 --- a/domain/consensus/processes/reachabilitymanager/tree.go +++ b/domain/consensus/processes/reachabilitymanager/tree.go @@ -814,7 +814,7 @@ func (rt *reachabilityManager) maybeMoveReindexRoot(reindexRoot, newTreeNode *ex return nil, false, err } - if newTreeNodeGHOSTDAGData.BlueScore-reindexRootChosenChildGHOSTDAGData.BlueScore < rt.reindexWindow { + if newTreeNodeGHOSTDAGData.BlueScore()-reindexRootChosenChildGHOSTDAGData.BlueScore() < rt.reindexWindow { return nil, false, nil } diff --git a/domain/consensus/processes/syncmanager/antipast.go b/domain/consensus/processes/syncmanager/antipast.go index 973b9efbf..7cdf339c1 100644 --- a/domain/consensus/processes/syncmanager/antipast.go +++ b/domain/consensus/processes/syncmanager/antipast.go @@ -16,12 +16,12 @@ func (sm *syncManager) antiPastHashesBetween(lowHash, highHash *externalapi.Doma if err != nil { return nil, err } - lowBlockBlueScore := lowBlockGHOSTDAGData.BlueScore + lowBlockBlueScore := lowBlockGHOSTDAGData.BlueScore() highBlockGHOSTDAGData, err := sm.ghostdagDataStore.Get(sm.databaseContext, highHash) if err != nil { return nil, err } - highBlockBlueScore := highBlockGHOSTDAGData.BlueScore + highBlockBlueScore := highBlockGHOSTDAGData.BlueScore() if lowBlockBlueScore >= highBlockBlueScore { return nil, errors.Errorf("low hash blueScore >= high hash blueScore (%d >= %d)", lowBlockBlueScore, highBlockBlueScore) @@ -37,7 +37,7 @@ func (sm *syncManager) antiPastHashesBetween(lowHash, highHash *externalapi.Doma // fairly accurate because we presume that most DAG blocks are // blue. for highBlockBlueScore-lowBlockBlueScore+1 > maxHashesInAntiPastHashesBetween { - highHash = highBlockGHOSTDAGData.SelectedParent + highHash = highBlockGHOSTDAGData.SelectedParent() } // Collect every node in highHash's past (including itself) but diff --git a/domain/consensus/processes/syncmanager/blocklocator.go b/domain/consensus/processes/syncmanager/blocklocator.go index a808e10ac..770b22ee6 100644 --- a/domain/consensus/processes/syncmanager/blocklocator.go +++ b/domain/consensus/processes/syncmanager/blocklocator.go @@ -14,13 +14,13 @@ func (sm *syncManager) createBlockLocator(lowHash, highHash *externalapi.DomainH if err != nil { return nil, err } - highHash = highBlockGHOSTDAGData.SelectedParent + highHash = highBlockGHOSTDAGData.SelectedParent() lowBlockGHOSTDAGData, err := sm.ghostdagDataStore.Get(sm.databaseContext, lowHash) if err != nil { return nil, err } - lowBlockBlueScore := lowBlockGHOSTDAGData.BlueScore + lowBlockBlueScore := lowBlockGHOSTDAGData.BlueScore() currentHash := highHash step := uint64(1) @@ -32,7 +32,7 @@ func (sm *syncManager) createBlockLocator(lowHash, highHash *externalapi.DomainH if err != nil { return nil, err } - currentBlockBlueScore := currentBlockGHOSTDAGData.BlueScore + currentBlockBlueScore := currentBlockGHOSTDAGData.BlueScore() // Nothing more to add once the low node has been added. if currentBlockBlueScore <= lowBlockBlueScore { @@ -47,7 +47,7 @@ func (sm *syncManager) createBlockLocator(lowHash, highHash *externalapi.DomainH // final node is lowNode. nextBlueScore := currentBlockBlueScore - step if currentBlockBlueScore < step { - nextBlueScore = lowBlockGHOSTDAGData.BlueScore + nextBlueScore = lowBlockGHOSTDAGData.BlueScore() } // Walk down currentHash's selected parent chain to the appropriate ancestor diff --git a/domain/consensus/processes/syncmanager/syncinfo.go b/domain/consensus/processes/syncmanager/syncinfo.go index 5d502b114..62a3f2a7b 100644 --- a/domain/consensus/processes/syncmanager/syncinfo.go +++ b/domain/consensus/processes/syncmanager/syncinfo.go @@ -91,7 +91,7 @@ func (sm *syncManager) virtualSelectedParentHash() (*externalapi.DomainHash, err if err != nil { return nil, err } - return virtualGHOSTDAGData.SelectedParent, nil + return virtualGHOSTDAGData.SelectedParent(), nil } func (sm *syncManager) headerVirtualSelectedParentHash() (*externalapi.DomainHash, error) { diff --git a/domain/consensus/processes/transactionvalidator/transaction_in_context.go b/domain/consensus/processes/transactionvalidator/transaction_in_context.go index 9f40f9998..57395bf42 100644 --- a/domain/consensus/processes/transactionvalidator/transaction_in_context.go +++ b/domain/consensus/processes/transactionvalidator/transaction_in_context.go @@ -59,7 +59,7 @@ func (v *transactionValidator) checkTransactionCoinbaseMaturity( return err } - txBlueScore := ghostdagData.BlueScore + txBlueScore := ghostdagData.BlueScore() var missingOutpoints []*externalapi.DomainOutpoint for _, input := range tx.Inputs { utxoEntry := input.UTXOEntry @@ -166,7 +166,7 @@ func (v *transactionValidator) checkTransactionSequenceLock(povBlockHash *extern return err } - if !v.sequenceLockActive(sequenceLock, ghostdagData.BlueScore, medianTime) { + if !v.sequenceLockActive(sequenceLock, ghostdagData.BlueScore(), medianTime) { return errors.Wrapf(ruleerrors.ErrUnfinalizedTx, "block contains "+ "transaction whose input sequence "+ "locks are not met") @@ -270,16 +270,16 @@ func (v *transactionValidator) calcTxSequenceLockFromReferencedUTXOEntries( for { selectedParentGHOSTDAGData, err := v.ghostdagDataStore.Get(v.databaseContext, - baseGHOSTDAGData.SelectedParent) + baseGHOSTDAGData.SelectedParent()) if err != nil { return nil, err } - if selectedParentGHOSTDAGData.BlueScore <= inputBlueScore { + if selectedParentGHOSTDAGData.BlueScore() <= inputBlueScore { break } - baseHash = baseGHOSTDAGData.SelectedParent + baseHash = baseGHOSTDAGData.SelectedParent() baseGHOSTDAGData = selectedParentGHOSTDAGData }