mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-28 01:36:42 +00:00

* Revert "[NOD-1500] Delete integration tests" This reverts commit fcb57a206690a884fa6afb69d5d493282954a8bf. * [NOD-1518] hashserialization -> consenusserialization * [NOD-1518] Fix add genesis to virtual * [NOD-1518] Fix a bug in SerializeCoinbasePayload. * [NOD-1518] Fix a loop error and make pastMedianTime behave correctly everywhere on genesis. * [NOD-1518] Fix another bug and an infinite loop. * [NOD-1518] Fix uninitialized slice. * [NOD-1518] Fix bad should-commit checks and another infinite loop. * [NOD-1518] Fix nil serialization. * [NOD-1518] Rename blockHash to currentBlockHash. * [NOD-1518] Move the check whether stagedVirtualUTXOSet != nil to the top of commitVirtualUTXODiff. * [NOD-1518] Simplify utxoDiffStore.Commit. * [NOD-1518] Unextract resolveBlockStatusAndCheckFinality. * [NOD-1518] Move no-transactions logic into CalculateIDMerkleRoot. * [NOD-1518] Remove redundant is-staged check. * [NOD-1518] Fix merge errors. * [NOD-1518] Don't write anything if utxoDiffChild is nil. * [NOD-1518] Stage virtualAcceptanceData and virtualMultiset. * [NOD-1518] Fix bugs in getBlockTemplate and submitBlock. * [NOD-1518] Fix bad validation order in validateHeaderInContext. * [NOD-1518] Fix bug in Next(). * [NOD-1518] Fix nil dereference of subnetworks in AddressCache. * [NOD-1518] Fix multisetStore.Get returning a pointer to a multiset that is changed in place. * [NOD-1518] Break on genesis in countSubtrees. * [NOD-1518] Fix createBlockLocator. * [NOD-1518] Fix MsgTxToDomainTransaction. * [NOD-1518] Set MaxTxVersion to 1. * [NOD-1518] Fix missing error handling, bug in MsgTxToDomainTransaction, and bad subnetwork equality check. * [NOD-1518] Fix bug in hasUTXOByOutpointFromStagedVirtualUTXODiff. * [NOD-1518] Remove irrelevant comments. * [NOD-1518] Generate transactions with sufficient fee in tx_relay_test. * [NOD-1518] Fix broken RPC handlers. * [NOD-1518] Fix merge errors. * [NOD-1518] Fix bad exists check in restorePastUTXO and missing genesis check in CalculatePastUTXOAndAcceptanceData. * [NOD-1518] Add a comment. * [NOD-1518] Use a regular mutex instead of a read-write mutex in consensus to avoid dealing with sneaky not-actually-read functions. * [NOD-1518] Fix a deadlock in GetVirtualSelectedParent. * [NOD-1518] Fix missing handler registration for CmdHeader. * [NOD-1518] Fix processHeader calling OnNewBlock and LogBlock. Also fix conversion errors in IBDRootUTXOSetAndBlock. * [NOD-1518] Fix bad Command() in MsgIBDRootUTXOSetAndBlock. * [NOD-1518] Fix bad SyncStateMissingUTXOSet logic in resolveSyncState. * [NOD-1518] Rename mode to syncState. * [NOD-1518] Fix headers-only blocks coming in after the consensus thinks it's synced. * [NOD-1518] Fix selectedChildIterator.Next not ignoring virtual, infinite loop in HashSet.Length(). * [NOD-1518] Fix not-properly wrapped IBD blocks. * [NOD-1518] Fix bad conversion in RequestIBDBlocks. * [NOD-1518] Fix bad string for CmdRequestHeaders. * [NOD-1518] Fix bad string for CmdDoneHeaders. * [NOD-1518] Fix bad Command() for MsgIBDRootNotFound. * [NOD-1518] Fix bad areHeaderTipsSyncedMaxTimeDifference value. * [NOD-1518] Add missing string for CmdRequestIBDBlocks. * [NOD-1518] Fix bad check for SyncStateMissingBlockBodies. * [NOD-1518] Fix bad timeout durations in tests. * [NOD-1518] Fix IBD blocks not calling OnNewBlock. * [NOD-1518] Change when IBD finishes. * [NOD-1518] Properly clone utxoDiffChild. * [NOD-1535] Fix reachability tests * [NOD-1518] Fix merge errors. * [NOD-1518] Move call to LogBlock to into OnNewBlock. * [NOD-1518] Return "not implemented" in unimplemented RPC handlers. * [NOD-1518] Extract cloning of hashes to a method over DomainHash. * [NOD-1518] Use isHeaderOnlyBlock. * [NOD-1518] Use constants.TransactionVersion. * [NOD-1518] Break immediately if we reached the virtual in SelectedChildIterator. * [NOD-1518] Don't stage nil utxoDiffChild. * [NOD-1518] Properly check the genesis hash in CalculatePastUTXOAndAcceptanceData. * [NOD-1518] Explain why we break on current == nil in countSubtrees. * [NOD-1518] Add a comment explaining why we check against StatusValid in resolveSyncState. * [NOD-1535] Add external reachability tests * [NOD-1535] Fix reachability tests and fix related bugs * [NOD-1535] Add setters fox reindex slack and window * [NOD-1535] Remove redundant line * [NOD-1535] Add comment * [NOD-1535] Fix comments * [NOD-1535] Rename DBReader->DatabaseContext * [NOD-1535] Check that reindex root is changed * [NOD-1535] Fix calculateNewTips Co-authored-by: Mike Zak <feanorr@gmail.com> Co-authored-by: stasatdaglabs <stas@daglabs.com>
337 lines
10 KiB
Go
337 lines
10 KiB
Go
package consensus
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/dagtraversalmanager"
|
|
"io/ioutil"
|
|
"math/rand"
|
|
"os"
|
|
"sync"
|
|
|
|
"github.com/kaspanet/kaspad/infrastructure/db/database/ldb"
|
|
|
|
consensusdatabase "github.com/kaspanet/kaspad/domain/consensus/database"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/acceptancedatastore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/blockheaderstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/blockrelationstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/blockstatusstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/blockstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/consensusstatestore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/ghostdagdatastore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/headertipsstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/multisetstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/pruningstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/reachabilitydatastore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/datastructures/utxodiffstore"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/blockbuilder"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/blockprocessor"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/blockvalidator"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/coinbasemanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/consensusstatemanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/dagtopologymanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/difficultymanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/headertipsmanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/mergedepthmanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/pastmediantimemanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/pruningmanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/reachabilitymanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/syncmanager"
|
|
"github.com/kaspanet/kaspad/domain/consensus/processes/transactionvalidator"
|
|
"github.com/kaspanet/kaspad/domain/dagconfig"
|
|
infrastructuredatabase "github.com/kaspanet/kaspad/infrastructure/db/database"
|
|
)
|
|
|
|
// Factory instantiates new Consensuses
|
|
type Factory interface {
|
|
NewConsensus(dagParams *dagconfig.Params, db infrastructuredatabase.Database) (externalapi.Consensus, error)
|
|
NewTestConsensus(dagParams *dagconfig.Params, testName string) (tc testapi.TestConsensus, teardown func(), err error)
|
|
}
|
|
|
|
type factory struct{}
|
|
|
|
// NewFactory creates a new Consensus factory
|
|
func NewFactory() Factory {
|
|
return &factory{}
|
|
}
|
|
|
|
// NewConsensus instantiates a new Consensus
|
|
func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredatabase.Database) (externalapi.Consensus, error) {
|
|
// Data Structures
|
|
acceptanceDataStore := acceptancedatastore.New()
|
|
blockStore := blockstore.New()
|
|
blockHeaderStore := blockheaderstore.New()
|
|
blockRelationStore := blockrelationstore.New()
|
|
blockStatusStore := blockstatusstore.New()
|
|
multisetStore := multisetstore.New()
|
|
pruningStore := pruningstore.New()
|
|
reachabilityDataStore := reachabilitydatastore.New()
|
|
utxoDiffStore := utxodiffstore.New()
|
|
consensusStateStore := consensusstatestore.New()
|
|
ghostdagDataStore := ghostdagdatastore.New()
|
|
headerTipsStore := headertipsstore.New()
|
|
|
|
dbManager := consensusdatabase.New(db)
|
|
|
|
// Processes
|
|
reachabilityManager := reachabilitymanager.New(
|
|
dbManager,
|
|
ghostdagDataStore,
|
|
reachabilityDataStore)
|
|
dagTopologyManager := dagtopologymanager.New(
|
|
dbManager,
|
|
reachabilityManager,
|
|
blockRelationStore)
|
|
ghostdagManager := ghostdagmanager.New(
|
|
dbManager,
|
|
dagTopologyManager,
|
|
ghostdagDataStore,
|
|
model.KType(dagParams.K))
|
|
dagTraversalManager := dagtraversalmanager.New(
|
|
dbManager,
|
|
dagTopologyManager,
|
|
ghostdagDataStore,
|
|
ghostdagManager)
|
|
pastMedianTimeManager := pastmediantimemanager.New(
|
|
dagParams.TimestampDeviationTolerance,
|
|
dbManager,
|
|
dagTraversalManager,
|
|
blockHeaderStore,
|
|
ghostdagDataStore)
|
|
transactionValidator := transactionvalidator.New(dagParams.BlockCoinbaseMaturity,
|
|
dagParams.EnableNonNativeSubnetworks,
|
|
dbManager,
|
|
pastMedianTimeManager,
|
|
ghostdagDataStore)
|
|
difficultyManager := difficultymanager.New(
|
|
dbManager,
|
|
ghostdagManager,
|
|
ghostdagDataStore,
|
|
blockHeaderStore,
|
|
dagTopologyManager,
|
|
dagTraversalManager,
|
|
dagParams.PowMax,
|
|
dagParams.DifficultyAdjustmentWindowSize,
|
|
dagParams.TargetTimePerBlock)
|
|
coinbaseManager := coinbasemanager.New(
|
|
dbManager,
|
|
ghostdagDataStore,
|
|
acceptanceDataStore)
|
|
headerTipsManager := headertipsmanager.New(dbManager, dagTopologyManager, ghostdagManager, headerTipsStore)
|
|
genesisHash := dagParams.GenesisHash
|
|
mergeDepthManager := mergedepthmanager.New(
|
|
dagParams.FinalityDepth(),
|
|
dbManager,
|
|
dagTopologyManager,
|
|
dagTraversalManager,
|
|
ghostdagDataStore)
|
|
blockValidator := blockvalidator.New(
|
|
dagParams.PowMax,
|
|
false,
|
|
genesisHash,
|
|
dagParams.EnableNonNativeSubnetworks,
|
|
dagParams.DisableDifficultyAdjustment,
|
|
dagParams.DifficultyAdjustmentWindowSize,
|
|
|
|
dbManager,
|
|
difficultyManager,
|
|
pastMedianTimeManager,
|
|
transactionValidator,
|
|
ghostdagManager,
|
|
dagTopologyManager,
|
|
dagTraversalManager,
|
|
coinbaseManager,
|
|
mergeDepthManager,
|
|
|
|
blockStore,
|
|
ghostdagDataStore,
|
|
blockHeaderStore,
|
|
blockStatusStore,
|
|
)
|
|
consensusStateManager, err := consensusstatemanager.New(
|
|
dbManager,
|
|
dagParams.FinalityDepth(),
|
|
dagParams.PruningDepth(),
|
|
genesisHash,
|
|
ghostdagManager,
|
|
dagTopologyManager,
|
|
dagTraversalManager,
|
|
pastMedianTimeManager,
|
|
transactionValidator,
|
|
blockValidator,
|
|
reachabilityManager,
|
|
coinbaseManager,
|
|
mergeDepthManager,
|
|
|
|
blockStatusStore,
|
|
ghostdagDataStore,
|
|
consensusStateStore,
|
|
multisetStore,
|
|
blockStore,
|
|
utxoDiffStore,
|
|
blockRelationStore,
|
|
acceptanceDataStore,
|
|
blockHeaderStore,
|
|
headerTipsStore)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pruningManager := pruningmanager.New(
|
|
dbManager,
|
|
dagTraversalManager,
|
|
dagTopologyManager,
|
|
consensusStateManager,
|
|
consensusStateStore,
|
|
ghostdagDataStore,
|
|
pruningStore,
|
|
blockStatusStore,
|
|
multisetStore,
|
|
acceptanceDataStore,
|
|
blockStore,
|
|
utxoDiffStore,
|
|
genesisHash,
|
|
dagParams.FinalityDepth(),
|
|
dagParams.PruningDepth())
|
|
|
|
syncManager := syncmanager.New(
|
|
dbManager,
|
|
genesisHash,
|
|
dagParams.TargetTimePerBlock.Milliseconds(),
|
|
dagTraversalManager,
|
|
dagTopologyManager,
|
|
ghostdagManager,
|
|
consensusStateManager,
|
|
|
|
ghostdagDataStore,
|
|
blockStatusStore,
|
|
blockHeaderStore,
|
|
headerTipsStore)
|
|
|
|
blockBuilder := blockbuilder.New(
|
|
dbManager,
|
|
difficultyManager,
|
|
pastMedianTimeManager,
|
|
coinbaseManager,
|
|
consensusStateManager,
|
|
ghostdagManager,
|
|
acceptanceDataStore,
|
|
blockRelationStore,
|
|
multisetStore,
|
|
ghostdagDataStore,
|
|
)
|
|
|
|
blockProcessor := blockprocessor.New(
|
|
dagParams,
|
|
dbManager,
|
|
consensusStateManager,
|
|
pruningManager,
|
|
blockValidator,
|
|
dagTopologyManager,
|
|
reachabilityManager,
|
|
difficultyManager,
|
|
pastMedianTimeManager,
|
|
ghostdagManager,
|
|
coinbaseManager,
|
|
headerTipsManager,
|
|
syncManager,
|
|
|
|
acceptanceDataStore,
|
|
blockStore,
|
|
blockStatusStore,
|
|
blockRelationStore,
|
|
multisetStore,
|
|
ghostdagDataStore,
|
|
consensusStateStore,
|
|
pruningStore,
|
|
reachabilityDataStore,
|
|
utxoDiffStore,
|
|
blockHeaderStore,
|
|
headerTipsStore)
|
|
|
|
c := &consensus{
|
|
lock: &sync.Mutex{},
|
|
databaseContext: dbManager,
|
|
|
|
blockProcessor: blockProcessor,
|
|
blockBuilder: blockBuilder,
|
|
consensusStateManager: consensusStateManager,
|
|
transactionValidator: transactionValidator,
|
|
syncManager: syncManager,
|
|
pastMedianTimeManager: pastMedianTimeManager,
|
|
blockValidator: blockValidator,
|
|
coinbaseManager: coinbaseManager,
|
|
dagTopologyManager: dagTopologyManager,
|
|
dagTraversalManager: dagTraversalManager,
|
|
difficultyManager: difficultyManager,
|
|
ghostdagManager: ghostdagManager,
|
|
headerTipsManager: headerTipsManager,
|
|
mergeDepthManager: mergeDepthManager,
|
|
pruningManager: pruningManager,
|
|
reachabilityManager: reachabilityManager,
|
|
|
|
blockStore: blockStore,
|
|
blockHeaderStore: blockHeaderStore,
|
|
pruningStore: pruningStore,
|
|
ghostdagDataStore: ghostdagDataStore,
|
|
blockStatusStore: blockStatusStore,
|
|
blockRelationStore: blockRelationStore,
|
|
consensusStateStore: consensusStateStore,
|
|
headerTipsStore: headerTipsStore,
|
|
multisetStore: multisetStore,
|
|
reachabilityDataStore: reachabilityDataStore,
|
|
}
|
|
|
|
genesisInfo, err := c.GetBlockInfo(genesisHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !genesisInfo.Exists {
|
|
err = c.ValidateAndInsertBlock(dagParams.GenesisBlock)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (f *factory) NewTestConsensus(dagParams *dagconfig.Params, testName string) (
|
|
tc testapi.TestConsensus, teardown func(), err error) {
|
|
|
|
testDatabaseDir, err := ioutil.TempDir("", testName)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
db, err := ldb.NewLevelDB(testDatabaseDir)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
consensusAsInterface, err := f.NewConsensus(dagParams, db)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
consensusAsImplementation := consensusAsInterface.(*consensus)
|
|
|
|
testBlockBuilder := blockbuilder.NewTestBlockBuilder(consensusAsImplementation.blockBuilder)
|
|
testConsensusStateManager := consensusstatemanager.NewTestConsensusStateManager(consensusAsImplementation.consensusStateManager)
|
|
tc = &testConsensus{
|
|
rd: rand.New(rand.NewSource(0)),
|
|
consensus: consensusAsImplementation,
|
|
testBlockBuilder: testBlockBuilder,
|
|
testConsensusStateManager: testConsensusStateManager,
|
|
testReachabilityManager: reachabilitymanager.NewTestReachabilityManager(consensusAsImplementation.
|
|
reachabilityManager),
|
|
}
|
|
teardown = func() {
|
|
db.Close()
|
|
os.RemoveAll(testDatabaseDir)
|
|
}
|
|
|
|
return tc, teardown, nil
|
|
}
|