mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* Pruning headers p2p basic structure * Remove headers-first * Fix consensus tests except TestValidateAndInsertPruningPointWithSideBlocks and TestValidateAndInsertImportedPruningPoint * Add virtual genesis * Implement PruningPointAndItsAnticoneWithMetaData * Start fixing TestValidateAndInsertImportedPruningPoint * Fix TestValidateAndInsertImportedPruningPoint * Fix BlockWindow * Update p2p and gRPC * Fix all tests except TestHandleRelayInvs * Delete TestHandleRelayInvs parts that cover the old IBD flow * Fix lint errors * Add p2p_request_ibd_blocks.go * Clean code * Make MsgBlockWithMetaData implement its own representation * Remove redundant check if highest share block is below the pruning point * Fix TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime * Fix comments, errors ane names * Fix window size to the real value * Check reindex root after each block at TestUpdateReindexRoot * Remove irrelevant check * Renames and comments * Remove redundant argument from sendGetBlockLocator * Don't delete staging on non-recoverable errors * Renames and comments * Remove redundant code * Commit changes inside ResolveVirtual * Add comment to IsRecoverableError * Remove blocksWithMetaDataGHOSTDAGDataStore * Increase windows pagefile * Move DeleteStagingConsensus outside of defer * Get rid of mustAccepted in receiveBlockWithMetaData * Ban on invalid pruning point * Rename interface_datastructures_daawindowstore.go to interface_datastructures_blocks_with_meta_data_daa_window_store.go * * Change GetVirtualSelectedParentChainFromBlockResponseMessage and VirtualSelectedParentChainChangedNotificationMessage to show only added block hashes * Remove ResolveVirtual * Use externalapi.ConsensusWrapper inside MiningManager * Fix pruningmanager.blockwithmetadata * Set pruning point selected child when importing the pruning point UTXO set * Change virtual genesis hash * replace the selected parent with virtual genesis on removePrunedBlocksFromGHOSTDAGData * Get rid of low hash in block locators * Remove +1 from everywhere we use difficultyAdjustmentWindowSize and increase the default value by one * Add comments about consensus wrapper * Don't use separate staging area when resolving resolveBlockStatus * Fix netsync stability test * Fix checkResolveVirtual * Rename ConsensusWrapper->ConsensusReference * Get rid of blockHeapNode * Add comment to defaultDifficultyAdjustmentWindowSize * Add SelectedChild to DAGTraversalManager * Remove redundant copy * Rename blockWindowHeap->calculateBlockWindowHeap * Move isVirtualGenesisOnlyParent to utils * Change BlockWithMetaData->BlockWithTrustedData * Get rid of maxReasonLength * Split IBD to 100 blocks each time * Fix a bug in calculateBlockWindowHeap * Switch to trusted data when encountering virtual genesis in blockWithTrustedData * Move ConsensusReference to domain * Update ConsensusReference comment * Add comment * Rename shouldNotAddGenesis->skipAddingGenesis
204 lines
5.1 KiB
Go
204 lines
5.1 KiB
Go
package domain
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensusreference"
|
|
"sync"
|
|
"sync/atomic"
|
|
"unsafe"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/miningmanager"
|
|
"github.com/kaspanet/kaspad/domain/miningmanager/mempool"
|
|
"github.com/kaspanet/kaspad/domain/prefixmanager"
|
|
"github.com/kaspanet/kaspad/domain/prefixmanager/prefix"
|
|
infrastructuredatabase "github.com/kaspanet/kaspad/infrastructure/db/database"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Domain provides a reference to the domain's external aps
|
|
type Domain interface {
|
|
MiningManager() miningmanager.MiningManager
|
|
Consensus() externalapi.Consensus
|
|
StagingConsensus() externalapi.Consensus
|
|
InitStagingConsensus() error
|
|
CommitStagingConsensus() error
|
|
DeleteStagingConsensus() error
|
|
}
|
|
|
|
type domain struct {
|
|
miningManager miningmanager.MiningManager
|
|
consensus *externalapi.Consensus
|
|
stagingConsensus *externalapi.Consensus
|
|
stagingConsensusLock sync.RWMutex
|
|
consensusConfig *consensus.Config
|
|
db infrastructuredatabase.Database
|
|
}
|
|
|
|
func (d *domain) Consensus() externalapi.Consensus {
|
|
return *d.consensus
|
|
}
|
|
|
|
func (d *domain) StagingConsensus() externalapi.Consensus {
|
|
d.stagingConsensusLock.RLock()
|
|
defer d.stagingConsensusLock.RUnlock()
|
|
return *d.stagingConsensus
|
|
}
|
|
|
|
func (d *domain) MiningManager() miningmanager.MiningManager {
|
|
return d.miningManager
|
|
}
|
|
|
|
func (d *domain) InitStagingConsensus() error {
|
|
d.stagingConsensusLock.Lock()
|
|
defer d.stagingConsensusLock.Unlock()
|
|
|
|
_, hasInactivePrefix, err := prefixmanager.InactivePrefix(d.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if hasInactivePrefix {
|
|
return errors.Errorf("cannot create staging consensus when a staging consensus already exists")
|
|
}
|
|
|
|
activePrefix, exists, err := prefixmanager.ActivePrefix(d.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !exists {
|
|
return errors.Errorf("cannot create a staging consensus when there's " +
|
|
"no active consensus")
|
|
}
|
|
|
|
inactivePrefix := activePrefix.Flip()
|
|
err = prefixmanager.SetPrefixAsInactive(d.db, inactivePrefix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
consensusFactory := consensus.NewFactory()
|
|
cfg := *d.consensusConfig
|
|
cfg.SkipAddingGenesis = true
|
|
|
|
consensusInstance, err := consensusFactory.NewConsensus(&cfg, d.db, inactivePrefix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
d.stagingConsensus = &consensusInstance
|
|
return nil
|
|
}
|
|
|
|
func (d *domain) CommitStagingConsensus() error {
|
|
d.stagingConsensusLock.Lock()
|
|
defer d.stagingConsensusLock.Unlock()
|
|
|
|
dbTx, err := d.db.Begin()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dbTx.RollbackUnlessClosed()
|
|
|
|
inactivePrefix, hasInactivePrefix, err := prefixmanager.InactivePrefix(d.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !hasInactivePrefix {
|
|
return errors.Errorf("there's no inactive prefix to commit")
|
|
}
|
|
|
|
activePrefix, exists, err := prefixmanager.ActivePrefix(dbTx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !exists {
|
|
return errors.Errorf("cannot commit a staging consensus when there's " +
|
|
"no active consensus")
|
|
}
|
|
|
|
err = prefixmanager.SetPrefixAsActive(dbTx, inactivePrefix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = prefixmanager.SetPrefixAsInactive(dbTx, activePrefix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = dbTx.Commit()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// We delete anything associated with the old prefix outside
|
|
// of the transaction in order to save memory.
|
|
err = prefixmanager.DeleteInactivePrefix(d.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tempConsensusPointer := unsafe.Pointer(d.stagingConsensus)
|
|
consensusPointer := (*unsafe.Pointer)(unsafe.Pointer(&d.consensus))
|
|
atomic.StorePointer(consensusPointer, tempConsensusPointer)
|
|
d.stagingConsensus = nil
|
|
return nil
|
|
}
|
|
|
|
func (d *domain) DeleteStagingConsensus() error {
|
|
d.stagingConsensusLock.Lock()
|
|
defer d.stagingConsensusLock.Unlock()
|
|
|
|
err := prefixmanager.DeleteInactivePrefix(d.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
d.stagingConsensus = nil
|
|
return nil
|
|
}
|
|
|
|
// New instantiates a new instance of a Domain object
|
|
func New(consensusConfig *consensus.Config, mempoolConfig *mempool.Config, db infrastructuredatabase.Database) (Domain, error) {
|
|
err := prefixmanager.DeleteInactivePrefix(db)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
activePrefix, exists, err := prefixmanager.ActivePrefix(db)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !exists {
|
|
activePrefix = &prefix.Prefix{}
|
|
err = prefixmanager.SetPrefixAsActive(db, activePrefix)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
consensusFactory := consensus.NewFactory()
|
|
consensusInstance, err := consensusFactory.NewConsensus(consensusConfig, db, activePrefix)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
domainInstance := &domain{
|
|
consensus: &consensusInstance,
|
|
consensusConfig: consensusConfig,
|
|
db: db,
|
|
}
|
|
|
|
miningManagerFactory := miningmanager.NewFactory()
|
|
|
|
// We create a consensus wrapper because the actual consensus might change
|
|
consensusReference := consensusreference.NewConsensusReference(&domainInstance.consensus)
|
|
domainInstance.miningManager = miningManagerFactory.NewMiningManager(consensusReference, &consensusConfig.Params, mempoolConfig)
|
|
return domainInstance, nil
|
|
}
|