From 81a10e9f8963b680ff84c0f78f631224fd6f8d46 Mon Sep 17 00:00:00 2001 From: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com> Date: Sun, 18 Oct 2020 12:34:00 +0300 Subject: [PATCH] [NOD-1458] Make further design changes (#956) * [NOD-1458] Rename RestoreUTXOSet to RestorePastUTXOSet. * [NOD-1458] Make CalculateAcceptanceDataAndMultiset take BlockGHOSTDAGData and nothing else. * [NOD-1458] Make ConsensusStateStore's Update take ConsensusStateChanges instead of just UTXODiff. * [NOD-1458] Add Tips() to ConsensusStateStore. * [NOD-1458] Make all implementation structs private. * [NOD-1458] Remove BlockAtDepth and add highHash to ChainBlockAtBlueScore. * [NOD-1458] Rename CalculateAcceptanceDataAndMultiset to CalculateAcceptanceDataAndUTXOMultiset. * [NOD-1458] Add a dependency to GHOSTDAGManager from ConsensusStateManager. * [NOD-1458] Add ChooseSelectedParent to GHOSTDAGManager. * [NOD-1458] Add DifficultyManager. * [NOD-1458] Add PastMedianTimeManager. * [NOD-1458] Add Hash() to Multiset. * [NOD-1458] Add a dependency to ghostdagManager from blockProcessor. * [NOD-1458] Add errors to all interfaces that need them. * [NOD-1458] Uppercasify types in comments. * [NOD-1458] Fix a bad comment. * [NOD-1458] Fix a comment. * [NOD-1458] Rename ChainBlockAtBlueScore to HighestChainBlockBelowBlueScore. * [NOD-1458] Replace BlockAndTransactionValidator with an anonymous interface. --- domain/consensus/consensus.go | 8 +-- .../acceptancedatastore.go | 26 +++++----- .../blockrelationstore/blockrelationstore.go | 16 +++--- .../blockstatusstore/blockstatusstore.go | 20 +++---- .../datastructures/blockstore/blockstore.go | 24 ++++----- .../consensusstatestore.go | 23 ++++---- .../feedatastore/feedatastore.go | 16 +++--- .../ghostdagdatastore/ghostdagdatastore.go | 16 +++--- .../multisetstore/multisetstore.go | 26 +++++----- .../pruningstore/pruningstore.go | 20 +++---- .../reachabilitydatastore.go | 16 +++--- .../utxodiffstore/utxodiffstore.go | 24 ++++----- domain/consensus/factory.go | 17 +++++- ...face_datastructures_acceptancedatastore.go | 6 +-- .../model/interface_datastructures_block.go | 8 +-- ...rface_datastructures_blockrelationstore.go | 4 +- ...terface_datastructures_blockstatusstore.go | 6 +-- ...face_datastructures_consensusstatestore.go | 5 +- .../interface_datastructures_feedatastore.go | 4 +- ...erface_datastructures_ghostdagdatastore.go | 4 +- .../interface_datastructures_multisetstore.go | 6 +-- .../interface_datastructures_pruningstore.go | 6 +-- ...ce_datastructures_reachabilitydatastore.go | 4 +- .../interface_datastructures_utxodiffstore.go | 8 +-- .../interface_processes_blockprocessor.go | 2 +- ...terface_processes_consensusstatemanager.go | 14 ++--- .../interface_processes_dagtopologymanager.go | 16 +++--- ...interface_processes_dagtraversalmanager.go | 5 +- .../interface_processes_difficultymanager.go | 7 +++ .../interface_processes_ghostdagmanager.go | 5 +- ...terface_processes_pastmediantimemanager.go | 7 +++ .../interface_processes_pruningmanager.go | 7 +-- .../interface_processes_reachabilitytree.go | 6 +-- domain/consensus/model/multiset.go | 1 + .../blockprocessor/blockprocessor.go | 37 ++++++++----- .../consensusstatemanager.go | 45 +++++++++------- .../dagtopologymanager/dagtopologymanager.go | 52 ++++++++++++------- .../dagtraversalmanager.go | 29 +++++------ .../difficultymanager/difficultymanager.go | 23 ++++++++ .../processes/ghostdagmanager/compare.go | 48 +++++++++++++---- .../processes/ghostdagmanager/ghostdag.go | 49 ++++++++++++----- .../ghostdagmanager/ghostdagmanager.go | 10 ++-- .../processes/ghostdagmanager/mergeset.go | 39 +++++++++++--- .../pastmediantimemanager.go | 23 ++++++++ .../pruningmanager/pruningmanager.go | 22 ++++---- .../reachabilitytree/reachabilitytree.go | 22 ++++---- .../processes/validator/validator.go | 35 ++++++++----- 47 files changed, 507 insertions(+), 310 deletions(-) create mode 100644 domain/consensus/model/interface_processes_difficultymanager.go create mode 100644 domain/consensus/model/interface_processes_pastmediantimemanager.go create mode 100644 domain/consensus/processes/difficultymanager/difficultymanager.go create mode 100644 domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go diff --git a/domain/consensus/consensus.go b/domain/consensus/consensus.go index 5bca5798d..95646ea95 100644 --- a/domain/consensus/consensus.go +++ b/domain/consensus/consensus.go @@ -6,9 +6,9 @@ import ( // Consensus maintains the current core state of the node type Consensus interface { - BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, transactionSelector model.TransactionSelector) *model.DomainBlock + BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, transactionSelector model.TransactionSelector) (*model.DomainBlock, error) ValidateAndInsertBlock(block *model.DomainBlock) error - UTXOByOutpoint(outpoint *model.DomainOutpoint) *model.UTXOEntry + UTXOByOutpoint(outpoint *model.DomainOutpoint) (*model.UTXOEntry, error) ValidateTransactionAndCalculateFee(transaction *model.DomainTransaction, utxoEntries []*model.UTXOEntry) (fee uint64, err error) } @@ -21,7 +21,7 @@ type consensus struct { // BuildBlock builds a block over the current state, with the transactions // selected by the given transactionSelector func (s *consensus) BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, - transactionSelector model.TransactionSelector) *model.DomainBlock { + transactionSelector model.TransactionSelector) (*model.DomainBlock, error) { return s.blockProcessor.BuildBlock(coinbaseScriptPublicKey, coinbaseExtraData, transactionSelector) } @@ -33,7 +33,7 @@ func (s *consensus) ValidateAndInsertBlock(block *model.DomainBlock) error { } // UTXOByOutpoint returns a UTXOEntry matching the given outpoint -func (s *consensus) UTXOByOutpoint(outpoint *model.DomainOutpoint) *model.UTXOEntry { +func (s *consensus) UTXOByOutpoint(outpoint *model.DomainOutpoint) (*model.UTXOEntry, error) { return s.consensusStateManager.UTXOByOutpoint(outpoint) } diff --git a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go index 14df42256..a0dcfb90f 100644 --- a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go +++ b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go @@ -4,26 +4,26 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// AcceptanceDataStore represents a store of AcceptanceData -type AcceptanceDataStore struct { +// acceptanceDataStore represents a store of AcceptanceData +type acceptanceDataStore struct { } // New instantiates a new AcceptanceDataStore -func New() *AcceptanceDataStore { - return &AcceptanceDataStore{} +func New() model.AcceptanceDataStore { + return &acceptanceDataStore{} } // Insert inserts the given acceptanceData for the given blockHash -func (ads *AcceptanceDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, acceptanceData *model.BlockAcceptanceData) { - -} - -// Get gets the acceptanceData associated with the given blockHash -func (ads *AcceptanceDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.BlockAcceptanceData { +func (ads *acceptanceDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, acceptanceData *model.BlockAcceptanceData) error { return nil } -// Delete deletes the acceptanceData associated with the given blockHash -func (ads *AcceptanceDataStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) { - +// Get gets the acceptanceData associated with the given blockHash +func (ads *acceptanceDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.BlockAcceptanceData, error) { + return nil, nil +} + +// Delete deletes the acceptanceData associated with the given blockHash +func (ads *acceptanceDataStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) error { + return nil } diff --git a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go index aced4b001..e543cbe0d 100644 --- a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go +++ b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go @@ -4,21 +4,21 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// BlockRelationStore represents a store of BlockRelations -type BlockRelationStore struct { +// blockRelationStore represents a store of BlockRelations +type blockRelationStore struct { } // New instantiates a new BlockRelationStore -func New() *BlockRelationStore { - return &BlockRelationStore{} +func New() model.BlockRelationStore { + return &blockRelationStore{} } // Insert inserts the given blockRelationData for the given blockHash -func (brs *BlockRelationStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockRelationData *model.BlockRelations) { - +func (brs *blockRelationStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockRelationData *model.BlockRelations) error { + return nil } // Get gets the blockRelationData associated with the given blockHash -func (brs *BlockRelationStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.BlockRelations { - return nil +func (brs *blockRelationStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.BlockRelations, error) { + return nil, nil } diff --git a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go index 2346d7913..295ab7b3c 100644 --- a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go +++ b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go @@ -4,26 +4,26 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// BlockStatusStore represents a store of BlockStatuses -type BlockStatusStore struct { +// blockStatusStore represents a store of BlockStatuses +type blockStatusStore struct { } // New instantiates a new BlockStatusStore -func New() *BlockStatusStore { - return &BlockStatusStore{} +func New() model.BlockStatusStore { + return &blockStatusStore{} } // Insert inserts the given blockStatus for the given blockHash -func (bss *BlockStatusStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockStatus model.BlockStatus) { - +func (bss *blockStatusStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockStatus model.BlockStatus) error { + return nil } // Get gets the blockStatus associated with the given blockHash -func (bss *BlockStatusStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) model.BlockStatus { - return 0 +func (bss *blockStatusStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (model.BlockStatus, error) { + return 0, nil } // Exists returns true if the blockStatus for the given blockHash exists -func (bss *BlockStatusStore) Exists(dbContext model.DBContextProxy, blockHash *model.DomainHash) bool { - return false +func (bss *blockStatusStore) Exists(dbContext model.DBContextProxy, blockHash *model.DomainHash) (bool, error) { + return false, nil } diff --git a/domain/consensus/datastructures/blockstore/blockstore.go b/domain/consensus/datastructures/blockstore/blockstore.go index 0e6218e8f..3ad1452ff 100644 --- a/domain/consensus/datastructures/blockstore/blockstore.go +++ b/domain/consensus/datastructures/blockstore/blockstore.go @@ -4,31 +4,31 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// BlockStore represents a store of blocks -type BlockStore struct { +// blockStore represents a store of blocks +type blockStore struct { } // New instantiates a new BlockStore -func New() *BlockStore { - return &BlockStore{} +func New() model.BlockStore { + return &blockStore{} } // Insert inserts the given block for the given blockHash -func (bms *BlockStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, msgBlock *model.DomainBlock) { - +func (bms *blockStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, msgBlock *model.DomainBlock) error { + return nil } // Block gets the block associated with the given blockHash -func (bms *BlockStore) Block(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.DomainBlock { - return nil +func (bms *blockStore) Block(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.DomainBlock, error) { + return nil, nil } // Blocks gets the blocks associated with the given blockHashes -func (bms *BlockStore) Blocks(dbContext model.DBContextProxy, blockHashes []*model.DomainHash) []*model.DomainBlock { - return nil +func (bms *blockStore) Blocks(dbContext model.DBContextProxy, blockHashes []*model.DomainHash) ([]*model.DomainBlock, error) { + return nil, nil } // Delete deletes the block associated with the given blockHash -func (bms *BlockStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) { - +func (bms *blockStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) error { + return nil } diff --git a/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go b/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go index f5f1f8efb..3f0c30b61 100644 --- a/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go +++ b/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go @@ -4,21 +4,26 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// ConsensusStateStore represents a store for the current consensus state -type ConsensusStateStore struct { +// consensusStateStore represents a store for the current consensus state +type consensusStateStore struct { } // New instantiates a new ConsensusStateStore -func New() *ConsensusStateStore { - return &ConsensusStateStore{} +func New() model.ConsensusStateStore { + return &consensusStateStore{} } -// Update updates the store with the given utxoDiff -func (css *ConsensusStateStore) Update(dbTx model.DBTxProxy, utxoDiff *model.UTXODiff) { - +// Update updates the store with the given consensusStateChanges +func (css *consensusStateStore) Update(dbTx model.DBTxProxy, consensusStateChanges *model.ConsensusStateChanges) error { + return nil } // UTXOByOutpoint gets the utxoEntry associated with the given outpoint -func (css *ConsensusStateStore) UTXOByOutpoint(dbContext model.DBContextProxy, outpoint *model.DomainOutpoint) *model.UTXOEntry { - return nil +func (css *consensusStateStore) UTXOByOutpoint(dbContext model.DBContextProxy, outpoint *model.DomainOutpoint) (*model.UTXOEntry, error) { + return nil, nil +} + +// Tips returns the current tips +func (css *consensusStateStore) Tips(dbContext model.DBContextProxy) ([]*model.DomainHash, error) { + return nil, nil } diff --git a/domain/consensus/datastructures/feedatastore/feedatastore.go b/domain/consensus/datastructures/feedatastore/feedatastore.go index 6e500af55..f8bdaa3cd 100644 --- a/domain/consensus/datastructures/feedatastore/feedatastore.go +++ b/domain/consensus/datastructures/feedatastore/feedatastore.go @@ -2,21 +2,21 @@ package feedatastore import "github.com/kaspanet/kaspad/domain/consensus/model" -// FeeDataStore represents a store of fee data -type FeeDataStore struct { +// feeDataStore represents a store of fee data +type feeDataStore struct { } // New instantiates a new FeeDataStore -func New() *FeeDataStore { - return &FeeDataStore{} +func New() model.FeeDataStore { + return &feeDataStore{} } // Insert inserts the given fee for the given blockHash -func (ads *FeeDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, fee uint64) { - +func (ads *feeDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, fee uint64) error { + return nil } // Get gets the fee associated with the given blockHash -func (ads *FeeDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) uint64 { - return 0 +func (ads *feeDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (uint64, error) { + return 0, nil } diff --git a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go index ef5f57814..99c010700 100644 --- a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go +++ b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go @@ -4,21 +4,21 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// GHOSTDAGDataStore represents a store of BlockGHOSTDAGData -type GHOSTDAGDataStore struct { +// ghostdagDataStore represents a store of BlockGHOSTDAGData +type ghostdagDataStore struct { } // New instantiates a new GHOSTDAGDataStore -func New() *GHOSTDAGDataStore { - return &GHOSTDAGDataStore{} +func New() model.GHOSTDAGDataStore { + return &ghostdagDataStore{} } // Insert inserts the given blockGHOSTDAGData for the given blockHash -func (gds *GHOSTDAGDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) { - +func (gds *ghostdagDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) error { + return nil } // Get gets the blockGHOSTDAGData associated with the given blockHash -func (gds *GHOSTDAGDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.BlockGHOSTDAGData { - return nil +func (gds *ghostdagDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.BlockGHOSTDAGData, error) { + return nil, nil } diff --git a/domain/consensus/datastructures/multisetstore/multisetstore.go b/domain/consensus/datastructures/multisetstore/multisetstore.go index f48863430..30fa93a22 100644 --- a/domain/consensus/datastructures/multisetstore/multisetstore.go +++ b/domain/consensus/datastructures/multisetstore/multisetstore.go @@ -4,26 +4,26 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// MultisetStore represents a store of Multisets -type MultisetStore struct { +// multisetStore represents a store of Multisets +type multisetStore struct { } // New instantiates a new MultisetStore -func New() *MultisetStore { - return &MultisetStore{} +func New() model.MultisetStore { + return &multisetStore{} } // Insert inserts the given multiset for the given blockHash -func (ms *MultisetStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, multiset model.Multiset) { - -} - -// Get gets the multiset associated with the given blockHash -func (ms *MultisetStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) model.Multiset { +func (ms *multisetStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, multiset model.Multiset) error { return nil } -// Delete deletes the multiset associated with the given blockHash -func (ms *MultisetStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) { - +// Get gets the multiset associated with the given blockHash +func (ms *multisetStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (model.Multiset, error) { + return nil, nil +} + +// Delete deletes the multiset associated with the given blockHash +func (ms *multisetStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) error { + return nil } diff --git a/domain/consensus/datastructures/pruningstore/pruningstore.go b/domain/consensus/datastructures/pruningstore/pruningstore.go index d480942f1..e1147eede 100644 --- a/domain/consensus/datastructures/pruningstore/pruningstore.go +++ b/domain/consensus/datastructures/pruningstore/pruningstore.go @@ -4,26 +4,26 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// PruningStore represents a store for the current pruning state -type PruningStore struct { +// pruningStore represents a store for the current pruning state +type pruningStore struct { } // New instantiates a new PruningStore -func New() *PruningStore { - return &PruningStore{} +func New() model.PruningStore { + return &pruningStore{} } // Update updates the pruning state -func (pps *PruningStore) Update(dbTx model.DBTxProxy, pruningPointBlockHash *model.DomainHash, pruningPointUTXOSet model.ReadOnlyUTXOSet) { - +func (pps *pruningStore) Update(dbTx model.DBTxProxy, pruningPointBlockHash *model.DomainHash, pruningPointUTXOSet model.ReadOnlyUTXOSet) error { + return nil } // PruningPoint gets the current pruning point -func (pps *PruningStore) PruningPoint(dbContext model.DBContextProxy) *model.DomainHash { - return nil +func (pps *pruningStore) PruningPoint(dbContext model.DBContextProxy) (*model.DomainHash, error) { + return nil, nil } // PruningPointSerializedUTXOSet returns the serialized UTXO set of the current pruning point -func (pps *PruningStore) PruningPointSerializedUTXOSet(dbContext model.DBContextProxy) []byte { - return nil +func (pps *pruningStore) PruningPointSerializedUTXOSet(dbContext model.DBContextProxy) ([]byte, error) { + return nil, nil } diff --git a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go index c96d755b5..d1990086e 100644 --- a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go +++ b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go @@ -4,21 +4,21 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// ReachabilityDataStore represents a store of ReachabilityData -type ReachabilityDataStore struct { +// reachabilityDataStore represents a store of ReachabilityData +type reachabilityDataStore struct { } // New instantiates a new ReachabilityDataStore -func New() *ReachabilityDataStore { - return &ReachabilityDataStore{} +func New() model.ReachabilityDataStore { + return &reachabilityDataStore{} } // Insert inserts the given reachabilityData for the given blockHash -func (rds *ReachabilityDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, reachabilityData *model.ReachabilityData) { - +func (rds *reachabilityDataStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, reachabilityData *model.ReachabilityData) error { + return nil } // Get gets the reachabilityData associated with the given blockHash -func (rds *ReachabilityDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.ReachabilityData { - return nil +func (rds *reachabilityDataStore) Get(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.ReachabilityData, error) { + return nil, nil } diff --git a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go index c97014a9e..5248149c6 100644 --- a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go +++ b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go @@ -4,31 +4,31 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// UTXODiffStore represents a store of UTXODiffs -type UTXODiffStore struct { +// utxoDiffStore represents a store of UTXODiffs +type utxoDiffStore struct { } // New instantiates a new UTXODiffStore -func New() *UTXODiffStore { - return &UTXODiffStore{} +func New() model.UTXODiffStore { + return &utxoDiffStore{} } // Insert inserts the given utxoDiff for the given blockHash -func (uds *UTXODiffStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, utxoDiff *model.UTXODiff, utxoDiffChild *model.DomainHash) { - +func (uds *utxoDiffStore) Insert(dbTx model.DBTxProxy, blockHash *model.DomainHash, utxoDiff *model.UTXODiff, utxoDiffChild *model.DomainHash) error { + return nil } // UTXODiff gets the utxoDiff associated with the given blockHash -func (uds *UTXODiffStore) UTXODiff(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.UTXODiff { - return nil +func (uds *utxoDiffStore) UTXODiff(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.UTXODiff, error) { + return nil, nil } // UTXODiffChild gets the utxoDiff child associated with the given blockHash -func (uds *UTXODiffStore) UTXODiffChild(dbContext model.DBContextProxy, blockHash *model.DomainHash) *model.DomainHash { - return nil +func (uds *utxoDiffStore) UTXODiffChild(dbContext model.DBContextProxy, blockHash *model.DomainHash) (*model.DomainHash, error) { + return nil, nil } // Delete deletes the utxoDiff associated with the given blockHash -func (uds *UTXODiffStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) { - +func (uds *utxoDiffStore) Delete(dbTx model.DBTxProxy, blockHash *model.DomainHash) error { + return nil } diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index 0661bb270..2fd621e81 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -18,7 +18,9 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/processes/consensusstatemanager" "github.com/kaspanet/kaspad/domain/consensus/processes/dagtopologymanager" "github.com/kaspanet/kaspad/domain/consensus/processes/dagtraversalmanager" + "github.com/kaspanet/kaspad/domain/consensus/processes/difficultymanager" "github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager" + "github.com/kaspanet/kaspad/domain/consensus/processes/pastmediantimemanager" "github.com/kaspanet/kaspad/domain/consensus/processes/pruningmanager" "github.com/kaspanet/kaspad/domain/consensus/processes/reachabilitytree" validatorpkg "github.com/kaspanet/kaspad/domain/consensus/processes/validator" @@ -72,14 +74,22 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, databaseContext *dba consensusStateStore, multisetStore, utxoDiffStore, - blockStore) + blockStore, + ghostdagManager) pruningManager := pruningmanager.New( dagTraversalManager, pruningStore, dagTopologyManager, blockStatusStore, consensusStateManager) - validator := validatorpkg.New(consensusStateManager) + difficultyManager := difficultymanager.New( + ghostdagManager) + pastMedianTimeManager := pastmediantimemanager.New( + ghostdagManager) + validator := validatorpkg.New( + consensusStateManager, + difficultyManager, + pastMedianTimeManager) blockProcessor := blockprocessor.New( dagParams, domainDBContext, @@ -88,6 +98,9 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, databaseContext *dba validator, dagTopologyManager, reachabilityTree, + difficultyManager, + pastMedianTimeManager, + ghostdagManager, acceptanceDataStore, blockStore, blockStatusStore, diff --git a/domain/consensus/model/interface_datastructures_acceptancedatastore.go b/domain/consensus/model/interface_datastructures_acceptancedatastore.go index 43d9d88ae..862149a77 100644 --- a/domain/consensus/model/interface_datastructures_acceptancedatastore.go +++ b/domain/consensus/model/interface_datastructures_acceptancedatastore.go @@ -2,7 +2,7 @@ package model // AcceptanceDataStore represents a store of AcceptanceData type AcceptanceDataStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, acceptanceData *BlockAcceptanceData) - Get(dbContext DBContextProxy, blockHash *DomainHash) *BlockAcceptanceData - Delete(dbTx DBTxProxy, blockHash *DomainHash) + Insert(dbTx DBTxProxy, blockHash *DomainHash, acceptanceData *BlockAcceptanceData) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (*BlockAcceptanceData, error) + Delete(dbTx DBTxProxy, blockHash *DomainHash) error } diff --git a/domain/consensus/model/interface_datastructures_block.go b/domain/consensus/model/interface_datastructures_block.go index 1d4010f36..ff941ccae 100644 --- a/domain/consensus/model/interface_datastructures_block.go +++ b/domain/consensus/model/interface_datastructures_block.go @@ -2,8 +2,8 @@ package model // BlockStore represents a store of blocks type BlockStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, block *DomainBlock) - Block(dbContext DBContextProxy, blockHash *DomainHash) *DomainBlock - Blocks(dbContext DBContextProxy, blockHashes []*DomainHash) []*DomainBlock - Delete(dbTx DBTxProxy, blockHash *DomainHash) + Insert(dbTx DBTxProxy, blockHash *DomainHash, block *DomainBlock) error + Block(dbContext DBContextProxy, blockHash *DomainHash) (*DomainBlock, error) + Blocks(dbContext DBContextProxy, blockHashes []*DomainHash) ([]*DomainBlock, error) + Delete(dbTx DBTxProxy, blockHash *DomainHash) error } diff --git a/domain/consensus/model/interface_datastructures_blockrelationstore.go b/domain/consensus/model/interface_datastructures_blockrelationstore.go index c24f657aa..a06ab77a4 100644 --- a/domain/consensus/model/interface_datastructures_blockrelationstore.go +++ b/domain/consensus/model/interface_datastructures_blockrelationstore.go @@ -2,6 +2,6 @@ package model // BlockRelationStore represents a store of BlockRelations type BlockRelationStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, blockRelationData *BlockRelations) - Get(dbContext DBContextProxy, blockHash *DomainHash) *BlockRelations + Insert(dbTx DBTxProxy, blockHash *DomainHash, blockRelationData *BlockRelations) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (*BlockRelations, error) } diff --git a/domain/consensus/model/interface_datastructures_blockstatusstore.go b/domain/consensus/model/interface_datastructures_blockstatusstore.go index ce099d165..bb7dda4db 100644 --- a/domain/consensus/model/interface_datastructures_blockstatusstore.go +++ b/domain/consensus/model/interface_datastructures_blockstatusstore.go @@ -2,7 +2,7 @@ package model // BlockStatusStore represents a store of BlockStatuses type BlockStatusStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, blockStatus BlockStatus) - Get(dbContext DBContextProxy, blockHash *DomainHash) BlockStatus - Exists(dbContext DBContextProxy, blockHash *DomainHash) bool + Insert(dbTx DBTxProxy, blockHash *DomainHash, blockStatus BlockStatus) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (BlockStatus, error) + Exists(dbContext DBContextProxy, blockHash *DomainHash) (bool, error) } diff --git a/domain/consensus/model/interface_datastructures_consensusstatestore.go b/domain/consensus/model/interface_datastructures_consensusstatestore.go index 61d46cf9c..53038f9a6 100644 --- a/domain/consensus/model/interface_datastructures_consensusstatestore.go +++ b/domain/consensus/model/interface_datastructures_consensusstatestore.go @@ -2,6 +2,7 @@ package model // ConsensusStateStore represents a store for the current consensus state type ConsensusStateStore interface { - Update(dbTx DBTxProxy, utxoDiff *UTXODiff) - UTXOByOutpoint(dbContext DBContextProxy, outpoint *DomainOutpoint) *UTXOEntry + Update(dbTx DBTxProxy, consensusStateChanges *ConsensusStateChanges) error + UTXOByOutpoint(dbContext DBContextProxy, outpoint *DomainOutpoint) (*UTXOEntry, error) + Tips(dbContext DBContextProxy) ([]*DomainHash, error) } diff --git a/domain/consensus/model/interface_datastructures_feedatastore.go b/domain/consensus/model/interface_datastructures_feedatastore.go index 091ba28d1..45ebca497 100644 --- a/domain/consensus/model/interface_datastructures_feedatastore.go +++ b/domain/consensus/model/interface_datastructures_feedatastore.go @@ -2,6 +2,6 @@ package model // FeeDataStore represents a store of fee data type FeeDataStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, fee uint64) - Get(dbContext DBContextProxy, blockHash *DomainHash) uint64 + Insert(dbTx DBTxProxy, blockHash *DomainHash, fee uint64) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (uint64, error) } diff --git a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go index f097a9d83..66e1188cc 100644 --- a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go +++ b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go @@ -2,6 +2,6 @@ package model // GHOSTDAGDataStore represents a store of BlockGHOSTDAGData type GHOSTDAGDataStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) - Get(dbContext DBContextProxy, blockHash *DomainHash) *BlockGHOSTDAGData + Insert(dbTx DBTxProxy, blockHash *DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (*BlockGHOSTDAGData, error) } diff --git a/domain/consensus/model/interface_datastructures_multisetstore.go b/domain/consensus/model/interface_datastructures_multisetstore.go index 004483c50..b63cc871a 100644 --- a/domain/consensus/model/interface_datastructures_multisetstore.go +++ b/domain/consensus/model/interface_datastructures_multisetstore.go @@ -2,7 +2,7 @@ package model // MultisetStore represents a store of Multisets type MultisetStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, multiset Multiset) - Get(dbContext DBContextProxy, blockHash *DomainHash) Multiset - Delete(dbTx DBTxProxy, blockHash *DomainHash) + Insert(dbTx DBTxProxy, blockHash *DomainHash, multiset Multiset) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (Multiset, error) + Delete(dbTx DBTxProxy, blockHash *DomainHash) error } diff --git a/domain/consensus/model/interface_datastructures_pruningstore.go b/domain/consensus/model/interface_datastructures_pruningstore.go index ab7d1b8c3..0828adbed 100644 --- a/domain/consensus/model/interface_datastructures_pruningstore.go +++ b/domain/consensus/model/interface_datastructures_pruningstore.go @@ -2,7 +2,7 @@ package model // PruningStore represents a store for the current pruning state type PruningStore interface { - Update(dbTx DBTxProxy, pruningPointBlockHash *DomainHash, pruningPointUTXOSet ReadOnlyUTXOSet) - PruningPoint(dbContext DBContextProxy) *DomainHash - PruningPointSerializedUTXOSet(dbContext DBContextProxy) []byte + Update(dbTx DBTxProxy, pruningPointBlockHash *DomainHash, pruningPointUTXOSet ReadOnlyUTXOSet) error + PruningPoint(dbContext DBContextProxy) (*DomainHash, error) + PruningPointSerializedUTXOSet(dbContext DBContextProxy) ([]byte, error) } diff --git a/domain/consensus/model/interface_datastructures_reachabilitydatastore.go b/domain/consensus/model/interface_datastructures_reachabilitydatastore.go index 901f1b50a..dd550aba3 100644 --- a/domain/consensus/model/interface_datastructures_reachabilitydatastore.go +++ b/domain/consensus/model/interface_datastructures_reachabilitydatastore.go @@ -2,6 +2,6 @@ package model // ReachabilityDataStore represents a store of ReachabilityData type ReachabilityDataStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, reachabilityData *ReachabilityData) - Get(dbContext DBContextProxy, blockHash *DomainHash) *ReachabilityData + Insert(dbTx DBTxProxy, blockHash *DomainHash, reachabilityData *ReachabilityData) error + Get(dbContext DBContextProxy, blockHash *DomainHash) (*ReachabilityData, error) } diff --git a/domain/consensus/model/interface_datastructures_utxodiffstore.go b/domain/consensus/model/interface_datastructures_utxodiffstore.go index fc288177f..884055df5 100644 --- a/domain/consensus/model/interface_datastructures_utxodiffstore.go +++ b/domain/consensus/model/interface_datastructures_utxodiffstore.go @@ -2,8 +2,8 @@ package model // UTXODiffStore represents a store of UTXODiffs type UTXODiffStore interface { - Insert(dbTx DBTxProxy, blockHash *DomainHash, utxoDiff *UTXODiff, utxoDiffChild *DomainHash) - UTXODiff(dbContext DBContextProxy, blockHash *DomainHash) *UTXODiff - UTXODiffChild(dbContext DBContextProxy, blockHash *DomainHash) *DomainHash - Delete(dbTx DBTxProxy, blockHash *DomainHash) + Insert(dbTx DBTxProxy, blockHash *DomainHash, utxoDiff *UTXODiff, utxoDiffChild *DomainHash) error + UTXODiff(dbContext DBContextProxy, blockHash *DomainHash) (*UTXODiff, error) + UTXODiffChild(dbContext DBContextProxy, blockHash *DomainHash) (*DomainHash, error) + Delete(dbTx DBTxProxy, blockHash *DomainHash) error } diff --git a/domain/consensus/model/interface_processes_blockprocessor.go b/domain/consensus/model/interface_processes_blockprocessor.go index b04e481a5..7562e32be 100644 --- a/domain/consensus/model/interface_processes_blockprocessor.go +++ b/domain/consensus/model/interface_processes_blockprocessor.go @@ -3,6 +3,6 @@ package model // BlockProcessor is responsible for processing incoming blocks // and creating blocks from the current state type BlockProcessor interface { - BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, transactionSelector TransactionSelector) *DomainBlock + BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, transactionSelector TransactionSelector) (*DomainBlock, error) ValidateAndInsertBlock(block *DomainBlock) error } diff --git a/domain/consensus/model/interface_processes_consensusstatemanager.go b/domain/consensus/model/interface_processes_consensusstatemanager.go index 68785bd86..97fa08de8 100644 --- a/domain/consensus/model/interface_processes_consensusstatemanager.go +++ b/domain/consensus/model/interface_processes_consensusstatemanager.go @@ -2,11 +2,11 @@ package model // ConsensusStateManager manages the node's consensus state type ConsensusStateManager interface { - UTXOByOutpoint(outpoint *DomainOutpoint) *UTXOEntry - CalculateConsensusStateChanges(block *DomainBlock, isDisqualified bool) ( - stateChanges *ConsensusStateChanges, utxoDiffChanges *UTXODiffChanges, virtualGHOSTDAGData *BlockGHOSTDAGData) - CalculateAcceptanceDataAndMultiset(blockHash *DomainHash) (*BlockAcceptanceData, Multiset) - Tips() []*DomainHash - VirtualData() (medianTime int64, blueScore uint64) - RestoreUTXOSet(blockHash *DomainHash) ReadOnlyUTXOSet + UTXOByOutpoint(outpoint *DomainOutpoint) (*UTXOEntry, error) + CalculateConsensusStateChanges(block *DomainBlock, isDisqualified bool) (stateChanges *ConsensusStateChanges, + utxoDiffChanges *UTXODiffChanges, virtualGHOSTDAGData *BlockGHOSTDAGData, err error) + CalculateAcceptanceDataAndUTXOMultiset(blockGHOSTDAGData *BlockGHOSTDAGData) (*BlockAcceptanceData, Multiset, error) + Tips() ([]*DomainHash, error) + VirtualData() (medianTime int64, blueScore uint64, err error) + RestorePastUTXOSet(blockHash *DomainHash) (ReadOnlyUTXOSet, error) } diff --git a/domain/consensus/model/interface_processes_dagtopologymanager.go b/domain/consensus/model/interface_processes_dagtopologymanager.go index acd284cf4..b41cf3bb7 100644 --- a/domain/consensus/model/interface_processes_dagtopologymanager.go +++ b/domain/consensus/model/interface_processes_dagtopologymanager.go @@ -3,12 +3,12 @@ package model // DAGTopologyManager exposes methods for querying relationships // between blocks in the DAG type DAGTopologyManager interface { - Parents(blockHash *DomainHash) []*DomainHash - Children(blockHash *DomainHash) []*DomainHash - IsParentOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - IsChildOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - IsAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - IsDescendantOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - IsAncestorOfAny(blockHash *DomainHash, potentialDescendants []*DomainHash) bool - IsInSelectedParentChainOf(blockHashA *DomainHash, blockHashB *DomainHash) bool + Parents(blockHash *DomainHash) ([]*DomainHash, error) + Children(blockHash *DomainHash) ([]*DomainHash, error) + IsParentOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + IsChildOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + IsAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + IsDescendantOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + IsAncestorOfAny(blockHash *DomainHash, potentialDescendants []*DomainHash) (bool, error) + IsInSelectedParentChainOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) } diff --git a/domain/consensus/model/interface_processes_dagtraversalmanager.go b/domain/consensus/model/interface_processes_dagtraversalmanager.go index dce3b8b2d..663dec356 100644 --- a/domain/consensus/model/interface_processes_dagtraversalmanager.go +++ b/domain/consensus/model/interface_processes_dagtraversalmanager.go @@ -3,7 +3,6 @@ package model // DAGTraversalManager exposes methods for travering blocks // in the DAG type DAGTraversalManager interface { - BlockAtDepth(highHash *DomainHash, depth uint64) *DomainHash - ChainBlockAtBlueScore(blueScore uint64) *DomainHash - SelectedParentIterator(highHash *DomainHash) SelectedParentIterator + HighestChainBlockBelowBlueScore(highHash *DomainHash, blueScore uint64) (*DomainHash, error) + SelectedParentIterator(highHash *DomainHash) (SelectedParentIterator, error) } diff --git a/domain/consensus/model/interface_processes_difficultymanager.go b/domain/consensus/model/interface_processes_difficultymanager.go new file mode 100644 index 000000000..c79a885af --- /dev/null +++ b/domain/consensus/model/interface_processes_difficultymanager.go @@ -0,0 +1,7 @@ +package model + +// DifficultyManager provides a method to resolve the +// difficulty value of a block +type DifficultyManager interface { + RequiredDifficulty(parents []*DomainHash) (uint32, error) +} diff --git a/domain/consensus/model/interface_processes_ghostdagmanager.go b/domain/consensus/model/interface_processes_ghostdagmanager.go index 15c3e0d73..fdac46174 100644 --- a/domain/consensus/model/interface_processes_ghostdagmanager.go +++ b/domain/consensus/model/interface_processes_ghostdagmanager.go @@ -3,5 +3,8 @@ package model // GHOSTDAGManager resolves and manages GHOSTDAG block data type GHOSTDAGManager interface { GHOSTDAG(blockParents []*DomainHash) (*BlockGHOSTDAGData, error) - BlockData(blockHash *DomainHash) *BlockGHOSTDAGData + BlockData(blockHash *DomainHash) (*BlockGHOSTDAGData, error) + ChooseSelectedParent( + blockHashA *DomainHash, blockAGHOSTDAGData *BlockGHOSTDAGData, + blockHashB *DomainHash, blockBGHOSTDAGData *BlockGHOSTDAGData) *DomainHash } diff --git a/domain/consensus/model/interface_processes_pastmediantimemanager.go b/domain/consensus/model/interface_processes_pastmediantimemanager.go new file mode 100644 index 000000000..f377d09a1 --- /dev/null +++ b/domain/consensus/model/interface_processes_pastmediantimemanager.go @@ -0,0 +1,7 @@ +package model + +// PastMedianTimeManager provides a method to resolve the +// past median time of a block +type PastMedianTimeManager interface { + PastMedianTime(blockGHOSTDAGData *BlockGHOSTDAGData) (int64, error) +} diff --git a/domain/consensus/model/interface_processes_pruningmanager.go b/domain/consensus/model/interface_processes_pruningmanager.go index 725c47274..1dfd984e9 100644 --- a/domain/consensus/model/interface_processes_pruningmanager.go +++ b/domain/consensus/model/interface_processes_pruningmanager.go @@ -2,7 +2,8 @@ package model // PruningManager resolves and manages the current pruning point type PruningManager interface { - FindNextPruningPoint(blockGHOSTDAGData *BlockGHOSTDAGData) (found bool, newPruningPoint *DomainHash, newPruningPointUTXOSet ReadOnlyUTXOSet) - PruningPoint() *DomainHash - SerializedUTXOSet() []byte + FindNextPruningPoint(blockGHOSTDAGData *BlockGHOSTDAGData) (found bool, + newPruningPoint *DomainHash, newPruningPointUTXOSet ReadOnlyUTXOSet, err error) + PruningPoint() (*DomainHash, error) + SerializedUTXOSet() ([]byte, error) } diff --git a/domain/consensus/model/interface_processes_reachabilitytree.go b/domain/consensus/model/interface_processes_reachabilitytree.go index bdde1947b..5b5bf4f01 100644 --- a/domain/consensus/model/interface_processes_reachabilitytree.go +++ b/domain/consensus/model/interface_processes_reachabilitytree.go @@ -3,7 +3,7 @@ package model // ReachabilityTree maintains a structure that allows to answer // reachability queries in sub-linear time type ReachabilityTree interface { - IsReachabilityTreeAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - IsDAGAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) bool - ReachabilityChangeset(blockHash *DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) *ReachabilityChangeset + IsReachabilityTreeAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + IsDAGAncestorOf(blockHashA *DomainHash, blockHashB *DomainHash) (bool, error) + ReachabilityChangeset(blockHash *DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) (*ReachabilityChangeset, error) } diff --git a/domain/consensus/model/multiset.go b/domain/consensus/model/multiset.go index 72e0e4f85..ff40219a4 100644 --- a/domain/consensus/model/multiset.go +++ b/domain/consensus/model/multiset.go @@ -4,4 +4,5 @@ package model type Multiset interface { Add(data []byte) Remove(data []byte) + Hash() *DomainHash } diff --git a/domain/consensus/processes/blockprocessor/blockprocessor.go b/domain/consensus/processes/blockprocessor/blockprocessor.go index 52d7f08e2..0230ea968 100644 --- a/domain/consensus/processes/blockprocessor/blockprocessor.go +++ b/domain/consensus/processes/blockprocessor/blockprocessor.go @@ -6,9 +6,9 @@ import ( "github.com/kaspanet/kaspad/domain/dagconfig" ) -// BlockProcessor is responsible for processing incoming blocks +// blockProcessor is responsible for processing incoming blocks // and creating blocks from the current state -type BlockProcessor struct { +type blockProcessor struct { dagParams *dagconfig.Params databaseContext *database.DomainDBContext @@ -17,6 +17,9 @@ type BlockProcessor struct { blockValidator model.BlockValidator dagTopologyManager model.DAGTopologyManager reachabilityTree model.ReachabilityTree + difficultyManager model.DifficultyManager + ghostdagManager model.GHOSTDAGManager + pastMedianTimeManager model.PastMedianTimeManager acceptanceDataStore model.AcceptanceDataStore blockMessageStore model.BlockStore blockStatusStore model.BlockStatusStore @@ -32,18 +35,24 @@ func New( blockValidator model.BlockValidator, dagTopologyManager model.DAGTopologyManager, reachabilityTree model.ReachabilityTree, + difficultyManager model.DifficultyManager, + pastMedianTimeManager model.PastMedianTimeManager, + ghostdagManager model.GHOSTDAGManager, acceptanceDataStore model.AcceptanceDataStore, blockMessageStore model.BlockStore, blockStatusStore model.BlockStatusStore, - feeDataStore model.FeeDataStore) *BlockProcessor { + feeDataStore model.FeeDataStore) model.BlockProcessor { - return &BlockProcessor{ - dagParams: dagParams, - databaseContext: databaseContext, - pruningManager: pruningManager, - blockValidator: blockValidator, - dagTopologyManager: dagTopologyManager, - reachabilityTree: reachabilityTree, + return &blockProcessor{ + dagParams: dagParams, + databaseContext: databaseContext, + pruningManager: pruningManager, + blockValidator: blockValidator, + dagTopologyManager: dagTopologyManager, + reachabilityTree: reachabilityTree, + difficultyManager: difficultyManager, + pastMedianTimeManager: pastMedianTimeManager, + ghostdagManager: ghostdagManager, consensusStateManager: consensusStateManager, acceptanceDataStore: acceptanceDataStore, @@ -55,14 +64,14 @@ func New( // BuildBlock builds a block over the current state, with the transactions // selected by the given transactionSelector -func (bp *BlockProcessor) BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, - transactionSelector model.TransactionSelector) *model.DomainBlock { +func (bp *blockProcessor) BuildBlock(coinbaseScriptPublicKey []byte, coinbaseExtraData []byte, + transactionSelector model.TransactionSelector) (*model.DomainBlock, error) { - return nil + return nil, nil } // ValidateAndInsertBlock validates the given block and, if valid, applies it // to the current state -func (bp *BlockProcessor) ValidateAndInsertBlock(block *model.DomainBlock) error { +func (bp *blockProcessor) ValidateAndInsertBlock(block *model.DomainBlock) error { return nil } diff --git a/domain/consensus/processes/consensusstatemanager/consensusstatemanager.go b/domain/consensus/processes/consensusstatemanager/consensusstatemanager.go index c9b026501..9a773030b 100644 --- a/domain/consensus/processes/consensusstatemanager/consensusstatemanager.go +++ b/domain/consensus/processes/consensusstatemanager/consensusstatemanager.go @@ -6,8 +6,8 @@ import ( "github.com/kaspanet/kaspad/domain/dagconfig" ) -// ConsensusStateManager manages the node's consensus state -type ConsensusStateManager struct { +// consensusStateManager manages the node's consensus state +type consensusStateManager struct { dagParams *dagconfig.Params databaseContext *database.DomainDBContext @@ -15,6 +15,7 @@ type ConsensusStateManager struct { multisetStore model.MultisetStore utxoDiffStore model.UTXODiffStore blockStore model.BlockStore + ghostdagManager model.GHOSTDAGManager } // New instantiates a new ConsensusStateManager @@ -24,9 +25,10 @@ func New( consensusStateStore model.ConsensusStateStore, multisetStore model.MultisetStore, utxoDiffStore model.UTXODiffStore, - blockStore model.BlockStore) *ConsensusStateManager { + blockStore model.BlockStore, + ghostdagManager model.GHOSTDAGManager) model.ConsensusStateManager { - return &ConsensusStateManager{ + return &consensusStateManager{ dagParams: dagParams, databaseContext: databaseContext, @@ -34,40 +36,43 @@ func New( multisetStore: multisetStore, utxoDiffStore: utxoDiffStore, blockStore: blockStore, + ghostdagManager: ghostdagManager, } } // UTXOByOutpoint returns a UTXOEntry matching the given outpoint -func (csm *ConsensusStateManager) UTXOByOutpoint(outpoint *model.DomainOutpoint) *model.UTXOEntry { - return nil +func (csm *consensusStateManager) UTXOByOutpoint(outpoint *model.DomainOutpoint) (*model.UTXOEntry, error) { + return nil, nil } // CalculateConsensusStateChanges returns a set of changes that must occur in order // to transition the current consensus state into the one including the given block -func (csm *ConsensusStateManager) CalculateConsensusStateChanges(block *model.DomainBlock, isDisqualified bool) ( +func (csm *consensusStateManager) CalculateConsensusStateChanges(block *model.DomainBlock, isDisqualified bool) ( stateChanges *model.ConsensusStateChanges, utxoDiffChanges *model.UTXODiffChanges, - virtualGHOSTDAGData *model.BlockGHOSTDAGData) { + virtualGHOSTDAGData *model.BlockGHOSTDAGData, err error) { + + return nil, nil, nil, nil +} + +// CalculateAcceptanceDataAndUTXOMultiset calculates and returns the acceptance data and the +// multiset associated with the given blockHash +func (csm *consensusStateManager) CalculateAcceptanceDataAndUTXOMultiset(blockGHOSTDAGData *model.BlockGHOSTDAGData) ( + *model.BlockAcceptanceData, model.Multiset, error) { return nil, nil, nil } -// CalculateAcceptanceDataAndMultiset calculates and returns the acceptance data and the -// multiset associated with the given blockHash -func (csm *ConsensusStateManager) CalculateAcceptanceDataAndMultiset(blockHash *model.DomainHash) (*model.BlockAcceptanceData, model.Multiset) { +// Tips returns the current DAG tips +func (csm *consensusStateManager) Tips() ([]*model.DomainHash, error) { return nil, nil } -// Tips returns the current DAG tips -func (csm *ConsensusStateManager) Tips() []*model.DomainHash { - return nil -} - // VirtualData returns the medianTime and blueScore of the current virtual block -func (csm *ConsensusStateManager) VirtualData() (medianTime int64, blueScore uint64) { - return 0, 0 +func (csm *consensusStateManager) VirtualData() (medianTime int64, blueScore uint64, err error) { + return 0, 0, nil } // RestoreUTXOSet calculates and returns the UTXOSet of the given blockHash -func (csm *ConsensusStateManager) RestoreUTXOSet(blockHash *model.DomainHash) model.ReadOnlyUTXOSet { - return nil +func (csm *consensusStateManager) RestorePastUTXOSet(blockHash *model.DomainHash) (model.ReadOnlyUTXOSet, error) { + return nil, nil } diff --git a/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go b/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go index 8387eb9cd..04fa02b61 100644 --- a/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go +++ b/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go @@ -5,9 +5,9 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// DAGTopologyManager exposes methods for querying relationships +// dagTopologyManager exposes methods for querying relationships // between blocks in the DAG -type DAGTopologyManager struct { +type dagTopologyManager struct { reachabilityTree model.ReachabilityTree blockRelationStore model.BlockRelationStore databaseContext *database.DomainDBContext @@ -17,9 +17,9 @@ type DAGTopologyManager struct { func New( databaseContext *database.DomainDBContext, reachabilityTree model.ReachabilityTree, - blockRelationStore model.BlockRelationStore) *DAGTopologyManager { + blockRelationStore model.BlockRelationStore) model.DAGTopologyManager { - return &DAGTopologyManager{ + return &dagTopologyManager{ databaseContext: databaseContext, reachabilityTree: reachabilityTree, blockRelationStore: blockRelationStore, @@ -27,43 +27,59 @@ func New( } // Parents returns the DAG parents of the given blockHash -func (dtm *DAGTopologyManager) Parents(blockHash *model.DomainHash) []*model.DomainHash { - return dtm.blockRelationStore.Get(dtm.databaseContext, blockHash).Parents +func (dtm *dagTopologyManager) Parents(blockHash *model.DomainHash) ([]*model.DomainHash, error) { + blockRelations, err := dtm.blockRelationStore.Get(dtm.databaseContext, blockHash) + if err != nil { + return nil, err + } + return blockRelations.Parents, nil } // Children returns the DAG children of the given blockHash -func (dtm *DAGTopologyManager) Children(blockHash *model.DomainHash) []*model.DomainHash { - return dtm.blockRelationStore.Get(dtm.databaseContext, blockHash).Children +func (dtm *dagTopologyManager) Children(blockHash *model.DomainHash) ([]*model.DomainHash, error) { + blockRelations, err := dtm.blockRelationStore.Get(dtm.databaseContext, blockHash) + if err != nil { + return nil, err + } + return blockRelations.Children, nil } // IsParentOf returns true if blockHashA is a direct DAG parent of blockHashB -func (dtm *DAGTopologyManager) IsParentOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { - return isHashInSlice(blockHashA, dtm.blockRelationStore.Get(dtm.databaseContext, blockHashB).Parents) +func (dtm *dagTopologyManager) IsParentOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { + blockRelations, err := dtm.blockRelationStore.Get(dtm.databaseContext, blockHashB) + if err != nil { + return false, err + } + return isHashInSlice(blockHashA, blockRelations.Parents), nil } // IsChildOf returns true if blockHashA is a direct DAG child of blockHashB -func (dtm *DAGTopologyManager) IsChildOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { - return isHashInSlice(blockHashA, dtm.blockRelationStore.Get(dtm.databaseContext, blockHashB).Children) +func (dtm *dagTopologyManager) IsChildOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { + blockRelations, err := dtm.blockRelationStore.Get(dtm.databaseContext, blockHashB) + if err != nil { + return false, err + } + return isHashInSlice(blockHashA, blockRelations.Children), nil } // IsAncestorOf returns true if blockHashA is a DAG ancestor of blockHashB -func (dtm *DAGTopologyManager) IsAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { +func (dtm *dagTopologyManager) IsAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { return dtm.reachabilityTree.IsDAGAncestorOf(blockHashA, blockHashB) } // IsDescendantOf returns true if blockHashA is a DAG descendant of blockHashB -func (dtm *DAGTopologyManager) IsDescendantOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { +func (dtm *dagTopologyManager) IsDescendantOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { return dtm.reachabilityTree.IsDAGAncestorOf(blockHashB, blockHashA) } // IsAncestorOfAny returns true if `blockHash` is an ancestor of at least one of `potentialDescendants` -func (dtm *DAGTopologyManager) IsAncestorOfAny(blockHash *model.DomainHash, potentialDescendants []*model.DomainHash) bool { - return false +func (dtm *dagTopologyManager) IsAncestorOfAny(blockHash *model.DomainHash, potentialDescendants []*model.DomainHash) (bool, error) { + return false, nil } // IsInSelectedParentChainOf returns true if blockHashA is in the selected parent chain of blockHashB -func (dtm *DAGTopologyManager) IsInSelectedParentChainOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { - return false +func (dtm *dagTopologyManager) IsInSelectedParentChainOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { + return false, nil } func isHashInSlice(hash *model.DomainHash, hashes []*model.DomainHash) bool { diff --git a/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go b/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go index 879f44f71..9a1c274a3 100644 --- a/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go +++ b/domain/consensus/processes/dagtraversalmanager/dagtraversalmanager.go @@ -4,9 +4,9 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// DAGTraversalManager exposes methods for travering blocks +// dagTraversalManager exposes methods for travering blocks // in the DAG -type DAGTraversalManager struct { +type dagTraversalManager struct { dagTopologyManager model.DAGTopologyManager ghostdagManager model.GHOSTDAGManager } @@ -14,28 +14,23 @@ type DAGTraversalManager struct { // New instantiates a new DAGTraversalManager func New( dagTopologyManager model.DAGTopologyManager, - ghostdagManager model.GHOSTDAGManager) *DAGTraversalManager { - return &DAGTraversalManager{ + ghostdagManager model.GHOSTDAGManager) model.DAGTraversalManager { + return &dagTraversalManager{ dagTopologyManager: dagTopologyManager, ghostdagManager: ghostdagManager, } } -// BlockAtDepth returns the hash of the block that's at the -// given depth from the given highHash -func (dtm *DAGTraversalManager) BlockAtDepth(highHash *model.DomainHash, depth uint64) *model.DomainHash { - return nil -} - // SelectedParentIterator creates an iterator over the selected // parent chain of the given highHash -func (dtm *DAGTraversalManager) SelectedParentIterator(highHash *model.DomainHash) model.SelectedParentIterator { - return nil +func (dtm *dagTraversalManager) SelectedParentIterator(highHash *model.DomainHash) (model.SelectedParentIterator, error) { + return nil, nil } -// ChainBlockAtBlueScore returns the hash of the smallest block -// with a blue score greater than the given blueScore in the -// virtual block's selected parent chain -func (dtm *DAGTraversalManager) ChainBlockAtBlueScore(blueScore uint64) *model.DomainHash { - return nil +// HighestChainBlockBelowBlueScore returns the hash of the +// highest block with a blue score lower than the given +// blueScore in the block with the given highHash's selected +// parent chain +func (dtm *dagTraversalManager) HighestChainBlockBelowBlueScore(highHash *model.DomainHash, blueScore uint64) (*model.DomainHash, error) { + return nil, nil } diff --git a/domain/consensus/processes/difficultymanager/difficultymanager.go b/domain/consensus/processes/difficultymanager/difficultymanager.go new file mode 100644 index 000000000..cd3231338 --- /dev/null +++ b/domain/consensus/processes/difficultymanager/difficultymanager.go @@ -0,0 +1,23 @@ +package difficultymanager + +import ( + "github.com/kaspanet/kaspad/domain/consensus/model" +) + +// DifficultyManager provides a method to resolve the +// difficulty value of a block +type difficultyManager struct { + ghostdagManager model.GHOSTDAGManager +} + +// New instantiates a new DifficultyManager +func New(ghostdagManager model.GHOSTDAGManager) model.DifficultyManager { + return &difficultyManager{ + ghostdagManager: ghostdagManager, + } +} + +// RequiredDifficulty returns the difficulty required for some block +func (dm *difficultyManager) RequiredDifficulty(parents []*model.DomainHash) (uint32, error) { + return 0, nil +} diff --git a/domain/consensus/processes/ghostdagmanager/compare.go b/domain/consensus/processes/ghostdagmanager/compare.go index 5fe4ac99c..616fe6d17 100644 --- a/domain/consensus/processes/ghostdagmanager/compare.go +++ b/domain/consensus/processes/ghostdagmanager/compare.go @@ -2,23 +2,53 @@ package ghostdagmanager import "github.com/kaspanet/kaspad/domain/consensus/model" -func (gm *GHOSTDAGManager) findSelectedParent(parentHashes []*model.DomainHash) *model.DomainHash { +func (gm *ghostdagManager) findSelectedParent(parentHashes []*model.DomainHash) (*model.DomainHash, error) { var selectedParent *model.DomainHash for _, hash := range parentHashes { - if selectedParent == nil || gm.less(selectedParent, hash) { + if selectedParent == nil { + selectedParent = hash + continue + } + isHashBiggerThanSelectedParent, err := gm.less(selectedParent, hash) + if err != nil { + return nil, err + } + if isHashBiggerThanSelectedParent { selectedParent = hash } } - return selectedParent + return selectedParent, nil } -func (gm *GHOSTDAGManager) less(blockA, blockB *model.DomainHash) bool { - blockABlueScore := gm.ghostdagDataStore.Get(gm.databaseContext, blockA).BlueScore - blockBBlueScore := gm.ghostdagDataStore.Get(gm.databaseContext, blockB).BlueScore - if blockABlueScore == blockBBlueScore { - return hashesLess(blockA, blockB) +func (gm *ghostdagManager) less(blockA, blockB *model.DomainHash) (bool, error) { + blockAGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, blockA) + if err != nil { + return false, err } - return blockABlueScore < blockBBlueScore + blockBGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, blockB) + if err != nil { + return false, err + } + chosenSelectedParent := gm.ChooseSelectedParent(blockA, blockAGHOSTDAGData, blockB, blockBGHOSTDAGData) + return chosenSelectedParent == blockB, nil +} + +func (gm *ghostdagManager) ChooseSelectedParent( + blockHashA *model.DomainHash, blockAGHOSTDAGData *model.BlockGHOSTDAGData, + blockHashB *model.DomainHash, blockBGHOSTDAGData *model.BlockGHOSTDAGData) *model.DomainHash { + + blockABlueScore := blockAGHOSTDAGData.BlueScore + blockBBlueScore := blockBGHOSTDAGData.BlueScore + if blockABlueScore == blockBBlueScore { + if hashesLess(blockHashA, blockHashB) { + return blockHashB + } + return blockHashA + } + if blockABlueScore < blockBBlueScore { + return blockHashB + } + return blockHashA } func hashesLess(a, b *model.DomainHash) bool { diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag.go b/domain/consensus/processes/ghostdagmanager/ghostdag.go index 73c93d559..fab480808 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdag.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdag.go @@ -23,15 +23,22 @@ import ( // BluesAnticoneSizes. // // For further details see the article https://eprint.iacr.org/2018/104.pdf -func (gm *GHOSTDAGManager) GHOSTDAG(blockParents []*model.DomainHash) (*model.BlockGHOSTDAGData, error) { +func (gm *ghostdagManager) GHOSTDAG(blockParents []*model.DomainHash) (*model.BlockGHOSTDAGData, error) { newBlockData := &model.BlockGHOSTDAGData{ MergeSetBlues: make([]*model.DomainHash, 0), MergeSetReds: make([]*model.DomainHash, 0), BluesAnticoneSizes: make(map[model.DomainHash]model.KType), } - newBlockData.SelectedParent = gm.findSelectedParent(blockParents) - mergeSet := gm.mergeSet(newBlockData.SelectedParent, blockParents) + selectedParent, err := gm.findSelectedParent(blockParents) + if err != nil { + return nil, err + } + newBlockData.SelectedParent = selectedParent + mergeSet, err := gm.mergeSet(newBlockData.SelectedParent, blockParents) + if err != nil { + return nil, err + } for _, blueCandidate := range mergeSet { isBlue, candidateAnticoneSize, candidateBluesAnticoneSizes, err := gm.checkBlueCandidate(newBlockData, blueCandidate) @@ -51,8 +58,11 @@ func (gm *GHOSTDAGManager) GHOSTDAG(blockParents []*model.DomainHash) (*model.Bl } } - newBlockData.BlueScore = gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.SelectedParent).BlueScore + - uint64(len(newBlockData.MergeSetBlues)) + selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.SelectedParent) + if err != nil { + return nil, err + } + newBlockData.BlueScore = selectedParentGHOSTDAGData.BlueScore + uint64(len(newBlockData.MergeSetBlues)) return newBlockData, nil } @@ -62,7 +72,7 @@ type chainBlockData struct { blockData *model.BlockGHOSTDAGData } -func (gm *GHOSTDAGManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGData, blueCandidate *model.DomainHash) ( +func (gm *ghostdagManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGData, blueCandidate *model.DomainHash) ( isBlue bool, candidateAnticoneSize model.KType, candidateBluesAnticoneSizes map[model.DomainHash]model.KType, err error) { // The maximum length of node.blues can be K+1 because @@ -96,15 +106,20 @@ func (gm *GHOSTDAGManager) checkBlueCandidate(newBlockData *model.BlockGHOSTDAGD return false, 0, nil, nil } + selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, chainBlock.blockData.SelectedParent) + if err != nil { + return false, 0, nil, err + } + chainBlock = chainBlockData{hash: chainBlock.blockData.SelectedParent, - blockData: gm.ghostdagDataStore.Get(gm.databaseContext, chainBlock.blockData.SelectedParent), + blockData: selectedParentGHOSTDAGData, } } return true, candidateAnticoneSize, candidateBluesAnticoneSizes, nil } -func (gm *GHOSTDAGManager) checkBlueCandidateWithChainBlock(newBlockData *model.BlockGHOSTDAGData, +func (gm *ghostdagManager) checkBlueCandidateWithChainBlock(newBlockData *model.BlockGHOSTDAGData, chainBlock chainBlockData, blueCandidate *model.DomainHash, candidateBluesAnticoneSizes map[model.DomainHash]model.KType, candidateAnticoneSize *model.KType) (isBlue, isRed bool, err error) { @@ -120,7 +135,10 @@ func (gm *GHOSTDAGManager) checkBlueCandidateWithChainBlock(newBlockData *model. // We check if chainBlock is not the new block by checking if it has a hash. if chainBlock.hash != nil { - isAncestorOfBlueCandidate := gm.dagTopologyManager.IsAncestorOf(chainBlock.hash, blueCandidate) + isAncestorOfBlueCandidate, err := gm.dagTopologyManager.IsAncestorOf(chainBlock.hash, blueCandidate) + if err != nil { + return false, false, err + } if isAncestorOfBlueCandidate { return true, false, nil } @@ -128,7 +146,10 @@ func (gm *GHOSTDAGManager) checkBlueCandidateWithChainBlock(newBlockData *model. for _, block := range chainBlock.blockData.MergeSetBlues { // Skip blocks that exist in the past of blueCandidate. - isAncestorOfBlueCandidate := gm.dagTopologyManager.IsAncestorOf(block, blueCandidate) + isAncestorOfBlueCandidate, err := gm.dagTopologyManager.IsAncestorOf(block, blueCandidate) + if err != nil { + return false, false, nil + } if isAncestorOfBlueCandidate { continue @@ -163,7 +184,7 @@ 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 *model.DomainHash, context *model.BlockGHOSTDAGData) (model.KType, error) { +func (gm *ghostdagManager) blueAnticoneSize(block *model.DomainHash, context *model.BlockGHOSTDAGData) (model.KType, error) { for current := context; current != nil; { if blueAnticoneSize, ok := current.BluesAnticoneSizes[*block]; ok { return blueAnticoneSize, nil @@ -171,7 +192,11 @@ func (gm *GHOSTDAGManager) blueAnticoneSize(block *model.DomainHash, context *mo if current.SelectedParent == nil { break } - current = gm.ghostdagDataStore.Get(gm.databaseContext, current.SelectedParent) + var err error + current, err = gm.ghostdagDataStore.Get(gm.databaseContext, current.SelectedParent) + if err != nil { + return 0, err + } } return 0, errors.Errorf("block %s is not in blue set of the given context", block) } diff --git a/domain/consensus/processes/ghostdagmanager/ghostdagmanager.go b/domain/consensus/processes/ghostdagmanager/ghostdagmanager.go index c50caa05d..e6212ead0 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdagmanager.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdagmanager.go @@ -6,8 +6,8 @@ import ( "github.com/kaspanet/kaspad/infrastructure/db/dbaccess" ) -// GHOSTDAGManager resolves and manages GHOSTDAG block data -type GHOSTDAGManager struct { +// ghostdagManager resolves and manages GHOSTDAG block data +type ghostdagManager struct { databaseContext *database.DomainDBContext dagTopologyManager model.DAGTopologyManager ghostdagDataStore model.GHOSTDAGDataStore @@ -19,9 +19,9 @@ func New( databaseContext *dbaccess.DatabaseContext, dagTopologyManager model.DAGTopologyManager, ghostdagDataStore model.GHOSTDAGDataStore, - k model.KType) *GHOSTDAGManager { + k model.KType) model.GHOSTDAGManager { - return &GHOSTDAGManager{ + return &ghostdagManager{ databaseContext: database.NewDomainDBContext(databaseContext), dagTopologyManager: dagTopologyManager, ghostdagDataStore: ghostdagDataStore, @@ -31,6 +31,6 @@ func New( // BlockData returns previously calculated GHOSTDAG data for // the given blockHash -func (gm *GHOSTDAGManager) BlockData(blockHash *model.DomainHash) *model.BlockGHOSTDAGData { +func (gm *ghostdagManager) BlockData(blockHash *model.DomainHash) (*model.BlockGHOSTDAGData, error) { return gm.ghostdagDataStore.Get(gm.databaseContext, blockHash) } diff --git a/domain/consensus/processes/ghostdagmanager/mergeset.go b/domain/consensus/processes/ghostdagmanager/mergeset.go index 01ca3ec9e..65ab33e67 100644 --- a/domain/consensus/processes/ghostdagmanager/mergeset.go +++ b/domain/consensus/processes/ghostdagmanager/mergeset.go @@ -5,8 +5,8 @@ import ( "sort" ) -func (gm *GHOSTDAGManager) mergeSet(selecteParent *model.DomainHash, - blockParents []*model.DomainHash) []*model.DomainHash { +func (gm *ghostdagManager) mergeSet(selecteParent *model.DomainHash, + blockParents []*model.DomainHash) ([]*model.DomainHash, error) { mergeSetMap := make(map[model.DomainHash]struct{}, gm.k) mergeSetSlice := make([]*model.DomainHash, 0, gm.k) @@ -27,7 +27,10 @@ func (gm *GHOSTDAGManager) mergeSet(selecteParent *model.DomainHash, current, queue = queue[0], queue[1:] // For each parent of the current block we check whether it is in the past of the selected parent. If not, // we add the it to the resulting anticone-set and queue it for further processing. - currentParents := gm.dagTopologyManager.Parents(current) + currentParents, err := gm.dagTopologyManager.Parents(current) + if err != nil { + return nil, err + } for _, parent := range currentParents { if _, ok := mergeSetMap[*parent]; ok { continue @@ -37,7 +40,10 @@ func (gm *GHOSTDAGManager) mergeSet(selecteParent *model.DomainHash, continue } - isAncestorOfSelectedParent := gm.dagTopologyManager.IsAncestorOf(parent, selecteParent) + isAncestorOfSelectedParent, err := gm.dagTopologyManager.IsAncestorOf(parent, selecteParent) + if err != nil { + return nil, err + } if isAncestorOfSelectedParent { selectedParentPast[*parent] = struct{}{} @@ -50,9 +56,26 @@ func (gm *GHOSTDAGManager) mergeSet(selecteParent *model.DomainHash, } } - sort.Slice(mergeSetSlice, func(i, j int) bool { - return gm.less(mergeSetSlice[i], mergeSetSlice[j]) - }) + err := gm.sortMergeSet(mergeSetSlice) + if err != nil { + return nil, err + } - return mergeSetSlice + return mergeSetSlice, nil +} + +func (gm *ghostdagManager) sortMergeSet(mergeSetSlice []*model.DomainHash) error { + var err error + sort.Slice(mergeSetSlice, func(i, j int) bool { + if err != nil { + return false + } + isLess, lessErr := gm.less(mergeSetSlice[i], mergeSetSlice[j]) + if lessErr != nil { + err = lessErr + return false + } + return isLess + }) + return err } diff --git a/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go new file mode 100644 index 000000000..b7d6679a7 --- /dev/null +++ b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go @@ -0,0 +1,23 @@ +package pastmediantimemanager + +import ( + "github.com/kaspanet/kaspad/domain/consensus/model" +) + +// pastMedianTimeManager provides a method to resolve the +// past median time of a block +type pastMedianTimeManager struct { + ghostdagManager model.GHOSTDAGManager +} + +// New instantiates a new PastMedianTimeManager +func New(ghostdagManager model.GHOSTDAGManager) model.PastMedianTimeManager { + return &pastMedianTimeManager{ + ghostdagManager: ghostdagManager, + } +} + +// PastMedianTime returns the past median time for some block +func (pmtm *pastMedianTimeManager) PastMedianTime(blockGHOSTDAGData *model.BlockGHOSTDAGData) (int64, error) { + return 0, nil +} diff --git a/domain/consensus/processes/pruningmanager/pruningmanager.go b/domain/consensus/processes/pruningmanager/pruningmanager.go index 4e357a0a8..bb363d303 100644 --- a/domain/consensus/processes/pruningmanager/pruningmanager.go +++ b/domain/consensus/processes/pruningmanager/pruningmanager.go @@ -4,8 +4,8 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// PruningManager resolves and manages the current pruning point -type PruningManager struct { +// pruningManager resolves and manages the current pruning point +type pruningManager struct { dagTraversalManager model.DAGTraversalManager pruningStore model.PruningStore dagTopologyManager model.DAGTopologyManager @@ -19,8 +19,8 @@ func New( pruningStore model.PruningStore, dagTopologyManager model.DAGTopologyManager, blockStatusStore model.BlockStatusStore, - consensusStateManager model.ConsensusStateManager) *PruningManager { - return &PruningManager{ + consensusStateManager model.ConsensusStateManager) model.PruningManager { + return &pruningManager{ dagTraversalManager: dagTraversalManager, pruningStore: pruningStore, dagTopologyManager: dagTopologyManager, @@ -31,19 +31,19 @@ func New( // FindNextPruningPoint finds the next pruning point from the // given blockHash. If none found, returns false -func (pm *PruningManager) FindNextPruningPoint(blockGHOSTDAGData *model.BlockGHOSTDAGData) (found bool, - newPruningPoint *model.DomainHash, newPruningPointUTXOSet model.ReadOnlyUTXOSet) { +func (pm *pruningManager) FindNextPruningPoint(blockGHOSTDAGData *model.BlockGHOSTDAGData) (found bool, + newPruningPoint *model.DomainHash, newPruningPointUTXOSet model.ReadOnlyUTXOSet, err error) { - return false, nil, nil + return false, nil, nil, nil } // PruningPoint returns the hash of the current pruning point -func (pm *PruningManager) PruningPoint() *model.DomainHash { - return nil +func (pm *pruningManager) PruningPoint() (*model.DomainHash, error) { + return nil, nil } // SerializedUTXOSet returns the serialized UTXO set of the // current pruning point -func (pm *PruningManager) SerializedUTXOSet() []byte { - return nil +func (pm *pruningManager) SerializedUTXOSet() ([]byte, error) { + return nil, nil } diff --git a/domain/consensus/processes/reachabilitytree/reachabilitytree.go b/domain/consensus/processes/reachabilitytree/reachabilitytree.go index b77ea909f..144eafd48 100644 --- a/domain/consensus/processes/reachabilitytree/reachabilitytree.go +++ b/domain/consensus/processes/reachabilitytree/reachabilitytree.go @@ -4,9 +4,9 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// ReachabilityTree maintains a structure that allows to answer +// reachabilityTree maintains a structure that allows to answer // reachability queries in sub-linear time -type ReachabilityTree struct { +type reachabilityTree struct { blockRelationStore model.BlockRelationStore reachabilityDataStore model.ReachabilityDataStore } @@ -14,8 +14,8 @@ type ReachabilityTree struct { // New instantiates a new ReachabilityTree func New( blockRelationStore model.BlockRelationStore, - reachabilityDataStore model.ReachabilityDataStore) *ReachabilityTree { - return &ReachabilityTree{ + reachabilityDataStore model.ReachabilityDataStore) model.ReachabilityTree { + return &reachabilityTree{ blockRelationStore: blockRelationStore, reachabilityDataStore: reachabilityDataStore, } @@ -24,20 +24,20 @@ func New( // IsReachabilityTreeAncestorOf returns true if blockHashA is an // ancestor of blockHashB in the reachability tree. Note that this // does not necessarily mean that it isn't its ancestor in the DAG. -func (rt *ReachabilityTree) IsReachabilityTreeAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { - return false +func (rt *reachabilityTree) IsReachabilityTreeAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { + return false, nil } // IsDAGAncestorOf returns true if blockHashA is an ancestor of // blockHashB in the DAG. -func (rt *ReachabilityTree) IsDAGAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) bool { - return false +func (rt *reachabilityTree) IsDAGAncestorOf(blockHashA *model.DomainHash, blockHashB *model.DomainHash) (bool, error) { + return false, nil } // ReachabilityChangeset returns a set of changes that need to occur // in order to add the given blockHash into the reachability tree. -func (rt *ReachabilityTree) ReachabilityChangeset(blockHash *model.DomainHash, - blockGHOSTDAGData *model.BlockGHOSTDAGData) *model.ReachabilityChangeset { +func (rt *reachabilityTree) ReachabilityChangeset(blockHash *model.DomainHash, + blockGHOSTDAGData *model.BlockGHOSTDAGData) (*model.ReachabilityChangeset, error) { - return nil + return nil, nil } diff --git a/domain/consensus/processes/validator/validator.go b/domain/consensus/processes/validator/validator.go index ee5c314a9..f42b87fd9 100644 --- a/domain/consensus/processes/validator/validator.go +++ b/domain/consensus/processes/validator/validator.go @@ -4,56 +4,67 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" ) -// Validator exposes a set of validation classes, after which +// validator exposes a set of validation classes, after which // it's possible to determine whether either a block or a // transaction is valid -type Validator struct { +type validator struct { consensusStateManager model.ConsensusStateManager + difficultyManager model.DifficultyManager + pastMedianTimeManager model.PastMedianTimeManager } -// New instantiates a new Validator -func New(consensusStateManager model.ConsensusStateManager) *Validator { - return &Validator{ +// New instantiates a new BlockAndTransactionValidator +func New( + consensusStateManager model.ConsensusStateManager, + difficultyManager model.DifficultyManager, + pastMedianTimeManager model.PastMedianTimeManager) interface { + model.BlockValidator + model.TransactionValidator +} { + + return &validator{ consensusStateManager: consensusStateManager, + difficultyManager: difficultyManager, + pastMedianTimeManager: pastMedianTimeManager, } } // ValidateHeaderInIsolation validates block headers in isolation from the current // consensus state -func (bv *Validator) ValidateHeaderInIsolation(block *model.DomainBlock) error { +func (v *validator) ValidateHeaderInIsolation(block *model.DomainBlock) error { return nil } // ValidateHeaderInContext validates block headers in the context of the current // consensus state -func (bv *Validator) ValidateHeaderInContext(block *model.DomainBlock) error { +func (v *validator) ValidateHeaderInContext(block *model.DomainBlock) error { return nil } // ValidateBodyInIsolation validates block bodies in isolation from the current // consensus state -func (bv *Validator) ValidateBodyInIsolation(block *model.DomainBlock) error { +func (v *validator) ValidateBodyInIsolation(block *model.DomainBlock) error { return nil } // ValidateBodyInContext validates block bodies in the context of the current // consensus state -func (bv *Validator) ValidateBodyInContext(block *model.DomainBlock) error { +func (v *validator) ValidateBodyInContext(block *model.DomainBlock) error { return nil } // ValidateAgainstPastUTXO validates the block against the UTXO of its past -func (bv *Validator) ValidateAgainstPastUTXO(block *model.DomainBlock) error { +func (v *validator) ValidateAgainstPastUTXO(block *model.DomainBlock) error { return nil } // ValidateFinality makes sure the block does not violate finality -func (bv *Validator) ValidateFinality(block *model.DomainBlock) error { +func (v *validator) ValidateFinality(block *model.DomainBlock) error { return nil } // ValidateTransactionAndCalculateFee validates the given transaction using // the given utxoEntries. It also returns the transaction's fee -func (bv *Validator) ValidateTransactionAndCalculateFee(transaction *model.DomainTransaction, utxoEntries []*model.UTXOEntry) (fee uint64, err error) { +func (v *validator) ValidateTransactionAndCalculateFee(transaction *model.DomainTransaction, utxoEntries []*model.UTXOEntry) (fee uint64, err error) { return 0, nil }