Allow to configure consensus (closes #1067)

* Allow to configure consensus with a JSON file

* Define everywhere maxBlockParents as KType

* Move consensus default to consensus_defaults.go
This commit is contained in:
Ori Newman 2020-12-03 08:30:01 -08:00 committed by GitHub
parent a585f32763
commit 32a04d1811
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 428 additions and 189 deletions

View File

@ -8,7 +8,6 @@ import (
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/blocks"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
@ -225,29 +224,6 @@ func (flow *handleRelayInvsFlow) processAndRelayBlock(requestQueue *hashesQueueS
missingParentsError := &ruleerrors.ErrMissingParents{}
if errors.As(err, missingParentsError) {
blueScore, err := blocks.ExtractBlueScore(block)
if err != nil {
return protocolerrors.Errorf(true, "received an orphan "+
"block %s with malformed blue score", blockHash)
}
const maxOrphanBlueScoreDiff = 10000
virtualSelectedParent, err := flow.Domain().Consensus().GetVirtualSelectedParent()
if err != nil {
return err
}
selectedTipBlueScore, err := blocks.ExtractBlueScore(virtualSelectedParent)
if err != nil {
return err
}
if blueScore > selectedTipBlueScore+maxOrphanBlueScoreDiff {
log.Infof("Orphan block %s has blue score %d and the selected tip blue score is "+
"%d. Ignoring orphans with a blue score difference from the selected tip greater than %d",
blockHash, blueScore, selectedTipBlueScore, maxOrphanBlueScoreDiff)
return nil
}
// Add the orphan to the orphan pool
flow.AddOrphan(block)

View File

@ -6,8 +6,6 @@ import (
"math/big"
"strconv"
"github.com/kaspanet/kaspad/domain/consensus/utils/blocks"
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
@ -27,7 +25,7 @@ func (ctx *Context) BuildBlockVerboseData(block *externalapi.DomainBlock, includ
hash := consensushashing.BlockHash(block)
blockHeader := block.Header
blueScore, err := blocks.ExtractBlueScore(block)
blockInfo, err := ctx.Domain.Consensus().GetBlockInfo(hash)
if err != nil {
return nil, err
}
@ -44,7 +42,7 @@ func (ctx *Context) BuildBlockVerboseData(block *externalapi.DomainBlock, includ
Time: blockHeader.TimeInMilliseconds,
Bits: strconv.FormatInt(int64(blockHeader.Bits), 16),
Difficulty: ctx.GetDifficultyRatio(blockHeader.Bits, ctx.Config.ActiveNetParams),
BlueScore: blueScore,
BlueScore: blockInfo.BlueScore,
}
txIDs := make([]string, len(block.Transactions))

View File

@ -129,6 +129,13 @@ func (s *consensus) GetBlockInfo(blockHash *externalapi.DomainHash) (*externalap
return blockInfo, nil
}
ghostdagData, err := s.ghostdagDataStore.Get(s.databaseContext, blockHash)
if err != nil {
return nil, err
}
blockInfo.BlueScore = ghostdagData.BlueScore
isBlockInHeaderPruningPointFuture, err := s.syncManager.IsBlockInHeaderPruningPointFuture(blockHash)
if err != nil {
return nil, err

View File

@ -22,7 +22,6 @@ import (
"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"
@ -97,7 +96,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
dbManager,
dagTopologyManager,
ghostdagDataStore,
model.KType(dagParams.K))
dagParams.K)
dagTraversalManager := dagtraversalmanager.New(
dbManager,
dagTopologyManager,
@ -111,6 +110,10 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
ghostdagDataStore)
transactionValidator := transactionvalidator.New(dagParams.BlockCoinbaseMaturity,
dagParams.EnableNonNativeSubnetworks,
dagParams.MassPerTxByte,
dagParams.MassPerScriptPubKeyByte,
dagParams.MassPerSigOp,
dagParams.MaxCoinbasePayloadLength,
dbManager,
pastMedianTimeManager,
ghostdagDataStore)
@ -123,9 +126,13 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
dagTraversalManager,
dagParams.PowMax,
dagParams.DifficultyAdjustmentWindowSize,
dagParams.TargetTimePerBlock)
dagParams.TargetTimePerBlock,
dagParams.GenesisHash)
coinbaseManager := coinbasemanager.New(
dbManager,
dagParams.SubsidyReductionInterval,
dagParams.BaseSubsidy,
dagParams.CoinbasePayloadScriptPublicKeyMaxLength,
ghostdagDataStore,
acceptanceDataStore)
headerTipsManager := headertipsmanager.New(dbManager, dagTopologyManager, ghostdagManager, headerTipsStore)
@ -143,6 +150,9 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
dagParams.EnableNonNativeSubnetworks,
dagParams.DisableDifficultyAdjustment,
dagParams.DifficultyAdjustmentWindowSize,
dagParams.MaxBlockSize,
dagParams.MergeSetSizeLimit,
dagParams.MaxBlockParents,
dbManager,
difficultyManager,
@ -164,7 +174,11 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
dbManager,
dagParams.FinalityDepth(),
dagParams.PruningDepth(),
dagParams.MaxMassAcceptedByBlock,
dagParams.MaxBlockParents,
dagParams.MergeSetSizeLimit,
genesisHash,
ghostdagManager,
dagTopologyManager,
dagTraversalManager,

View File

@ -4,6 +4,7 @@ package externalapi
type BlockInfo struct {
Exists bool
BlockStatus BlockStatus
BlueScore uint64
IsBlockInHeaderPruningPointFuture bool
}

View File

@ -7,4 +7,6 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
type CoinbaseManager interface {
ExpectedCoinbaseTransaction(blockHash *externalapi.DomainHash,
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error)
ExtractCoinbaseDataAndBlueScore(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64,
coinbaseData *externalapi.DomainCoinbaseData, err error)
}

View File

@ -3,9 +3,7 @@ package blockvalidator
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/coinbase"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
@ -85,7 +83,7 @@ func (v *blockValidator) ValidateBodyInIsolation(blockHash *externalapi.DomainHa
}
func (v *blockValidator) checkCoinbase(block *externalapi.DomainBlock) error {
_, _, err := coinbase.ExtractCoinbaseDataAndBlueScore(block.Transactions[transactionhelper.CoinbaseTransactionIndex])
_, _, err := v.coinbaseManager.ExtractCoinbaseDataAndBlueScore(block.Transactions[transactionhelper.CoinbaseTransactionIndex])
if err != nil {
return err
}
@ -214,9 +212,9 @@ func (v *blockValidator) checkBlockSize(block *externalapi.DomainBlock) error {
for _, tx := range block.Transactions {
sizeBefore := size
size += estimatedsize.TransactionEstimatedSerializedSize(tx)
if size > constants.MaxBlockSize || size < sizeBefore {
if size > v.maxBlockSize || size < sizeBefore {
return errors.Wrapf(ruleerrors.ErrBlockSizeTooHigh, "block excceeded the size limit of %d",
constants.MaxBlockSize)
v.maxBlockSize)
}
}

View File

@ -4,7 +4,6 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/pkg/errors"
)
@ -118,9 +117,9 @@ func (v *blockValidator) checkMergeSizeLimit(hash *externalapi.DomainHash) error
mergeSetSize := len(ghostdagData.MergeSetReds) + len(ghostdagData.MergeSetBlues)
if mergeSetSize > constants.MergeSetSizeLimit {
if uint64(mergeSetSize) > v.mergeSetSizeLimit {
return errors.Wrapf(ruleerrors.ErrViolatingMergeLimit,
"The block merges %d blocks > %d merge set size limit", mergeSetSize, constants.MergeSetSizeLimit)
"The block merges %d blocks > %d merge set size limit", mergeSetSize, v.mergeSetSizeLimit)
}
return nil

View File

@ -4,7 +4,6 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/pkg/errors"
)
@ -30,9 +29,9 @@ func (v *blockValidator) checkParentsLimit(header *externalapi.DomainBlockHeader
return errors.Wrapf(ruleerrors.ErrNoParents, "block has no parents")
}
if len(header.ParentHashes) > constants.MaxBlockParents {
if uint64(len(header.ParentHashes)) > uint64(v.maxBlockParents) {
return errors.Wrapf(ruleerrors.ErrTooManyParents, "block header has %d parents, but the maximum allowed amount "+
"is %d", len(header.ParentHashes), constants.MaxBlockParents)
"is %d", len(header.ParentHashes), v.maxBlockParents)
}
return nil
}

View File

@ -18,6 +18,9 @@ type blockValidator struct {
disableDifficultyAdjustment bool
powMaxBits uint32
difficultyAdjustmentWindowSize uint64
maxBlockSize uint64
mergeSetSizeLimit uint64
maxBlockParents model.KType
databaseContext model.DBReader
difficultyManager model.DifficultyManager
@ -43,6 +46,10 @@ func New(powMax *big.Int,
enableNonNativeSubnetworks bool,
disableDifficultyAdjustment bool,
difficultyAdjustmentWindowSize uint64,
maxBlockSize uint64,
mergeSetSizeLimit uint64,
maxBlockParents model.KType,
databaseContext model.DBReader,
difficultyManager model.DifficultyManager,
@ -68,16 +75,20 @@ func New(powMax *big.Int,
disableDifficultyAdjustment: disableDifficultyAdjustment,
powMaxBits: util.BigToCompact(powMax),
difficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
databaseContext: databaseContext,
difficultyManager: difficultyManager,
pastMedianTimeManager: pastMedianTimeManager,
transactionValidator: transactionValidator,
ghostdagManager: ghostdagManager,
dagTopologyManager: dagTopologyManager,
dagTraversalManager: dagTraversalManager,
coinbaseManager: coinbaseManager,
mergeDepthManager: mergeDepthManager,
pruningStore: pruningStore,
maxBlockSize: maxBlockSize,
mergeSetSizeLimit: mergeSetSizeLimit,
maxBlockParents: maxBlockParents,
databaseContext: databaseContext,
difficultyManager: difficultyManager,
pastMedianTimeManager: pastMedianTimeManager,
transactionValidator: transactionValidator,
ghostdagManager: ghostdagManager,
dagTopologyManager: dagTopologyManager,
dagTraversalManager: dagTraversalManager,
coinbaseManager: coinbaseManager,
mergeDepthManager: mergeDepthManager,
pruningStore: pruningStore,
blockStore: blockStore,
ghostdagDataStore: ghostdagDataStore,

View File

@ -3,14 +3,15 @@ package coinbasemanager
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/coinbase"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
)
type coinbaseManager struct {
subsidyReductionInterval uint64
subsidyReductionInterval uint64
baseSubsidy uint64
coinbasePayloadScriptPublicKeyMaxLength uint64
databaseContext model.DBReader
ghostdagDataStore model.GHOSTDAGDataStore
@ -42,7 +43,7 @@ func (c coinbaseManager) ExpectedCoinbaseTransaction(blockHash *externalapi.Doma
}
}
payload, err := coinbase.SerializeCoinbasePayload(ghostdagData.BlueScore, coinbaseData)
payload, err := c.serializeCoinbasePayload(ghostdagData.BlueScore, coinbaseData)
if err != nil {
return nil, err
}
@ -85,7 +86,7 @@ func (c coinbaseManager) coinbaseOutputForBlueBlock(blueBlock *externalapi.Domai
}
// the ScriptPubKey for the coinbase is parsed from the coinbase payload
_, coinbaseData, err := coinbase.ExtractCoinbaseDataAndBlueScore(blockAcceptanceData.TransactionAcceptanceData[0].Transaction)
_, coinbaseData, err := c.ExtractCoinbaseDataAndBlueScore(blockAcceptanceData.TransactionAcceptanceData[0].Transaction)
if err != nil {
return nil, false, err
}
@ -110,7 +111,7 @@ func (c coinbaseManager) coinbaseOutputForBlueBlock(blueBlock *externalapi.Domai
// approximately every 4 years.
func (c coinbaseManager) calcBlockSubsidy(blockHash *externalapi.DomainHash) (uint64, error) {
if c.subsidyReductionInterval == 0 {
return constants.BaseSubsidy, nil
return c.baseSubsidy, nil
}
ghostdagData, err := c.ghostdagDataStore.Get(c.databaseContext, blockHash)
@ -119,17 +120,27 @@ func (c coinbaseManager) calcBlockSubsidy(blockHash *externalapi.DomainHash) (ui
}
// Equivalent to: baseSubsidy / 2^(blueScore/subsidyHalvingInterval)
return constants.BaseSubsidy >> uint(ghostdagData.BlueScore/c.subsidyReductionInterval), nil
return c.baseSubsidy >> uint(ghostdagData.BlueScore/c.subsidyReductionInterval), nil
}
// New instantiates a new CoinbaseManager
func New(
databaseContext model.DBReader,
subsidyReductionInterval uint64,
baseSubsidy uint64,
coinbasePayloadScriptPublicKeyMaxLength uint64,
ghostdagDataStore model.GHOSTDAGDataStore,
acceptanceDataStore model.AcceptanceDataStore) model.CoinbaseManager {
return &coinbaseManager{
databaseContext: databaseContext,
databaseContext: databaseContext,
subsidyReductionInterval: subsidyReductionInterval,
baseSubsidy: baseSubsidy,
coinbasePayloadScriptPublicKeyMaxLength: coinbasePayloadScriptPublicKeyMaxLength,
ghostdagDataStore: ghostdagDataStore,
acceptanceDataStore: acceptanceDataStore,
}

View File

@ -1,4 +1,4 @@
package coinbase
package coinbasemanager
import (
"encoding/binary"
@ -6,7 +6,6 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/pkg/errors"
)
@ -15,12 +14,12 @@ var byteOrder = binary.LittleEndian
const uint64Len = 8
const lengthOfscriptPubKeyLength = 1
// SerializeCoinbasePayload builds the coinbase payload based on the provided scriptPubKey and extra data.
func SerializeCoinbasePayload(blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData) ([]byte, error) {
// serializeCoinbasePayload builds the coinbase payload based on the provided scriptPubKey and extra data.
func (c coinbaseManager) serializeCoinbasePayload(blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData) ([]byte, error) {
scriptPubKeyLength := len(coinbaseData.ScriptPublicKey)
if scriptPubKeyLength > constants.CoinbasePayloadScriptPublicKeyMaxLength {
if uint64(scriptPubKeyLength) > c.coinbasePayloadScriptPublicKeyMaxLength {
return nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen, "coinbase's payload script public key is "+
"longer than the max allowed length of %d", constants.CoinbasePayloadScriptPublicKeyMaxLength)
"longer than the max allowed length of %d", c.coinbasePayloadScriptPublicKeyMaxLength)
}
payload := make([]byte, uint64Len+lengthOfscriptPubKeyLength+scriptPubKeyLength+len(coinbaseData.ExtraData))
@ -35,7 +34,7 @@ func SerializeCoinbasePayload(blueScore uint64, coinbaseData *externalapi.Domain
}
// ExtractCoinbaseDataAndBlueScore deserializes the coinbase payload to its component (scriptPubKey and extra data).
func ExtractCoinbaseDataAndBlueScore(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64,
func (c coinbaseManager) ExtractCoinbaseDataAndBlueScore(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64,
coinbaseData *externalapi.DomainCoinbaseData, err error) {
minLength := uint64Len + lengthOfscriptPubKeyLength
@ -47,9 +46,9 @@ func ExtractCoinbaseDataAndBlueScore(coinbaseTx *externalapi.DomainTransaction)
blueScore = byteOrder.Uint64(coinbaseTx.Payload[:uint64Len])
scriptPubKeyLength := coinbaseTx.Payload[uint64Len]
if scriptPubKeyLength > constants.CoinbasePayloadScriptPublicKeyMaxLength {
if uint64(scriptPubKeyLength) > c.coinbasePayloadScriptPublicKeyMaxLength {
return 0, nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen, "coinbase's payload script public key is "+
"longer than the max allowed length of %d", constants.CoinbasePayloadScriptPublicKeyMaxLength)
"longer than the max allowed length of %d", c.coinbasePayloadScriptPublicKeyMaxLength)
}
if len(coinbaseTx.Payload) < minLength+int(scriptPubKeyLength) {

View File

@ -2,7 +2,6 @@ package consensusstatemanager
import (
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/pkg/errors"
@ -242,7 +241,7 @@ func (csm *consensusStateManager) checkTransactionMass(
// We could potentially overflow the accumulator so check for
// overflow as well.
if accumulatedMassAfter < transaction.Mass || accumulatedMassAfter > constants.MaxMassAcceptedByBlock {
if accumulatedMassAfter < transaction.Mass || accumulatedMassAfter > csm.maxMassAcceptedByBlock {
return false, 0
}

View File

@ -7,10 +7,13 @@ import (
// consensusStateManager manages the node's consensus state
type consensusStateManager struct {
finalityDepth uint64
pruningDepth uint64
genesisHash *externalapi.DomainHash
databaseContext model.DBManager
finalityDepth uint64
pruningDepth uint64
maxMassAcceptedByBlock uint64
maxBlockParents model.KType
mergeSetSizeLimit uint64
genesisHash *externalapi.DomainHash
databaseContext model.DBManager
ghostdagManager model.GHOSTDAGManager
dagTopologyManager model.DAGTopologyManager
@ -41,7 +44,11 @@ func New(
databaseContext model.DBManager,
finalityDepth uint64,
pruningDepth uint64,
maxMassAcceptedByBlock uint64,
maxBlockParents model.KType,
mergeSetSizeLimit uint64,
genesisHash *externalapi.DomainHash,
ghostdagManager model.GHOSTDAGManager,
dagTopologyManager model.DAGTopologyManager,
dagTraversalManager model.DAGTraversalManager,
@ -64,10 +71,13 @@ func New(
headerTipsStore model.HeaderTipsStore) (model.ConsensusStateManager, error) {
csm := &consensusStateManager{
finalityDepth: finalityDepth,
pruningDepth: pruningDepth,
genesisHash: genesisHash,
databaseContext: databaseContext,
finalityDepth: finalityDepth,
pruningDepth: pruningDepth,
maxMassAcceptedByBlock: maxMassAcceptedByBlock,
maxBlockParents: maxBlockParents,
mergeSetSizeLimit: mergeSetSizeLimit,
genesisHash: genesisHash,
databaseContext: databaseContext,
ghostdagManager: ghostdagManager,
dagTopologyManager: dagTopologyManager,

View File

@ -5,7 +5,6 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/hashset"
)
@ -34,9 +33,9 @@ func (csm *consensusStateManager) pickVirtualParents(tips []*externalapi.DomainH
selectedVirtualParents := hashset.NewFromSlice(virtualSelectedParent)
mergeSetSize := 1 // starts counting from 1 because selectedParent is already in the mergeSet
mergeSetSize := uint64(1) // starts counting from 1 because selectedParent is already in the mergeSet
for candidatesHeap.Len() > 0 && len(selectedVirtualParents) < constants.MaxBlockParents {
for candidatesHeap.Len() > 0 && uint64(len(selectedVirtualParents)) < uint64(csm.maxBlockParents) {
candidate := candidatesHeap.Pop()
log.Tracef("Attempting to add %s to the virtual parents", candidate)
@ -48,7 +47,7 @@ func (csm *consensusStateManager) pickVirtualParents(tips []*externalapi.DomainH
}
log.Tracef("The merge set would increase by %d with block %s", mergeSetIncrease, candidate)
if mergeSetSize+mergeSetIncrease > constants.MergeSetSizeLimit {
if mergeSetSize+mergeSetIncrease > csm.mergeSetSizeLimit {
log.Tracef("Cannot add block %s since that would violate the merge set size limit", candidate)
continue
}
@ -130,7 +129,7 @@ func (csm *consensusStateManager) selectVirtualSelectedParent(
}
func (csm *consensusStateManager) mergeSetIncrease(
candidate *externalapi.DomainHash, selectedVirtualParents hashset.HashSet) (int, error) {
candidate *externalapi.DomainHash, selectedVirtualParents hashset.HashSet) (uint64, error) {
log.Tracef("mergeSetIncrease start")
defer log.Tracef("mergeSetIncrease end")
@ -141,7 +140,7 @@ func (csm *consensusStateManager) mergeSetIncrease(
if err != nil {
return 0, err
}
mergeSetIncrease := 1 // starts with 1 for the candidate itself
mergeSetIncrease := uint64(1) // starts with 1 for the candidate itself
for queue.Len() > 0 {
current := queue.Pop()

View File

@ -5,7 +5,6 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
"github.com/kaspanet/kaspad/domain/consensus/utils/coinbase"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
@ -157,7 +156,7 @@ func (csm *consensusStateManager) validateCoinbaseTransaction(blockHash *externa
log.Tracef("Extracting coinbase data for coinbase transaction %s in block %s",
consensushashing.TransactionID(coinbaseTransaction), blockHash)
_, coinbaseData, err := coinbase.ExtractCoinbaseDataAndBlueScore(coinbaseTransaction)
_, coinbaseData, err := csm.coinbaseManager.ExtractCoinbaseDataAndBlueScore(coinbaseTransaction)
if err != nil {
return err
}

View File

@ -18,6 +18,7 @@ type difficultyManager struct {
headerStore model.BlockHeaderStore
dagTopologyManager model.DAGTopologyManager
dagTraversalManager model.DAGTraversalManager
genesisHash *externalapi.DomainHash
powMax *big.Int
difficultyAdjustmentWindowSize uint64
targetTimePerBlock time.Duration
@ -34,6 +35,7 @@ func New(
powMax *big.Int,
difficultyAdjustmentWindowSize uint64,
targetTimePerBlock time.Duration,
genesisHash *externalapi.DomainHash,
) model.DifficultyManager {
return &difficultyManager{
databaseContext: databaseContext,
@ -45,9 +47,19 @@ func New(
powMax: powMax,
difficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
targetTimePerBlock: targetTimePerBlock,
genesisHash: genesisHash,
}
}
func (dm *difficultyManager) genesisBits() (uint32, error) {
header, err := dm.headerStore.BlockHeader(dm.databaseContext, dm.genesisHash)
if err != nil {
return 0, err
}
return header.Bits, nil
}
// RequiredDifficulty returns the difficulty required for some block
func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHash) (uint32, error) {
@ -57,7 +69,7 @@ func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHas
}
// Genesis block
if len(parents) == 0 {
return util.BigToCompact(dm.powMax), nil
return dm.genesisBits()
}
// find bluestParent
@ -83,7 +95,7 @@ func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHas
// Not enough blocks for building a difficulty window.
if bluestGhostDAG.BlueScore < dm.difficultyAdjustmentWindowSize+1 {
return util.BigToCompact(dm.powMax), nil
return dm.genesisBits()
}
// Fetch window of dag.difficultyAdjustmentWindowSize + 1 so we can have dag.difficultyAdjustmentWindowSize block intervals

View File

@ -3,7 +3,6 @@ package transactionvalidator
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
@ -17,7 +16,7 @@ func (v *transactionValidator) transactionMassStandalonePart(tx *externalapi.Dom
totalScriptPubKeySize += uint64(len(output.ScriptPublicKey))
}
return size*constants.MassPerTxByte + totalScriptPubKeySize*constants.MassPerScriptPubKeyByte
return size*v.massPerTxByte + totalScriptPubKeySize*v.massPerScriptPubKeyByte
}
func (v *transactionValidator) transactionMass(tx *externalapi.DomainTransaction) (uint64, error) {
@ -44,5 +43,5 @@ func (v *transactionValidator) transactionMass(tx *externalapi.DomainTransaction
return 0, ruleerrors.NewErrMissingTxOut(missingOutpoints)
}
return standaloneMass + sigOpsCount*constants.MassPerSigOp, nil
return standaloneMass + sigOpsCount*v.massPerSigOp, nil
}

View File

@ -116,10 +116,10 @@ func (v *transactionValidator) checkCoinbaseLength(tx *externalapi.DomainTransac
// Coinbase payload length must not exceed the max length.
payloadLen := len(tx.Payload)
if payloadLen > constants.MaxCoinbasePayloadLength {
if uint64(payloadLen) > v.maxCoinbasePayloadLength {
return errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen, "coinbase transaction payload length "+
"of %d is out of range (max: %d)",
payloadLen, constants.MaxCoinbasePayloadLength)
payloadLen, v.maxCoinbasePayloadLength)
}
return nil

View File

@ -79,7 +79,7 @@ func TestValidateTransactionInIsolation(t *testing.T) {
1,
1,
subnetworks.SubnetworkIDNative,
&txSubnetworkData{subnetworks.SubnetworkIDCoinbase, 0, make([]byte, constants.MaxCoinbasePayloadLength+1)},
&txSubnetworkData{subnetworks.SubnetworkIDCoinbase, 0, make([]byte, params.MaxCoinbasePayloadLength+1)},
nil,
ruleerrors.ErrBadCoinbasePayloadLen},
{"non-zero gas in Kaspa", 1, 1, 0,

View File

@ -15,18 +15,30 @@ type transactionValidator struct {
pastMedianTimeManager model.PastMedianTimeManager
ghostdagDataStore model.GHOSTDAGDataStore
enableNonNativeSubnetworks bool
massPerTxByte uint64
massPerScriptPubKeyByte uint64
massPerSigOp uint64
maxCoinbasePayloadLength uint64
sigCache *txscript.SigCache
}
// New instantiates a new TransactionValidator
func New(blockCoinbaseMaturity uint64,
enableNonNativeSubnetworks bool,
massPerTxByte uint64,
massPerScriptPubKeyByte uint64,
massPerSigOp uint64,
maxCoinbasePayloadLength uint64,
databaseContext model.DBReader,
pastMedianTimeManager model.PastMedianTimeManager,
ghostdagDataStore model.GHOSTDAGDataStore) model.TransactionValidator {
return &transactionValidator{
blockCoinbaseMaturity: blockCoinbaseMaturity,
enableNonNativeSubnetworks: enableNonNativeSubnetworks,
massPerTxByte: massPerTxByte,
massPerScriptPubKeyByte: massPerScriptPubKeyByte,
massPerSigOp: massPerSigOp,
maxCoinbasePayloadLength: maxCoinbasePayloadLength,
databaseContext: databaseContext,
pastMedianTimeManager: pastMedianTimeManager,
ghostdagDataStore: ghostdagDataStore,

View File

@ -1,22 +0,0 @@
package blocks
import (
"errors"
"github.com/kaspanet/kaspad/domain/consensus/utils/coinbase"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
)
// ExtractBlueScore extracts the block's blue score out of it's coinbase transaction's payload
func ExtractBlueScore(block *externalapi.DomainBlock) (uint64, error) {
if len(block.Transactions) < transactionhelper.CoinbaseTransactionIndex+1 {
return 0, errors.New("Block has no coinbase transaction")
}
coinbaseTransaction := block.Transactions[transactionhelper.CoinbaseTransactionIndex]
blueScore, _, err := coinbase.ExtractCoinbaseDataAndBlueScore(coinbaseTransaction)
return blueScore, err
}

View File

@ -16,39 +16,6 @@ const (
// MaxSompi is the maximum transaction amount allowed in sompi.
MaxSompi = 21_000_000 * SompiPerKaspa
// MaxCoinbasePayloadLength is the maximum length in bites allowed for a block's coinbase's payload
MaxCoinbasePayloadLength = 150
// MaxBlockSize is the maximum size in bytes a block is allowed
MaxBlockSize = 1_000_000
// MaxBlockParents is the maximum number of blocks a block is allowed to point to
MaxBlockParents = 10
// MassPerTxByte is the number of grams that any byte
// adds to a transaction.
MassPerTxByte = 1
// MassPerScriptPubKeyByte is the number of grams that any
// scriptPubKey byte adds to a transaction.
MassPerScriptPubKeyByte = 10
// MassPerSigOp is the number of grams that any
// signature operation adds to a transaction.
MassPerSigOp = 10000
// MergeSetSizeLimit is the maximum number of blocks in a block's merge set
MergeSetSizeLimit = 1000
// MaxMassAcceptedByBlock is the maximum total transaction mass a block may accept.
MaxMassAcceptedByBlock = 10000000
// BaseSubsidy is the starting subsidy amount for mined blocks.
BaseSubsidy = 50 * SompiPerKaspa
// CoinbasePayloadScriptPublicKeyMaxLength is the maximum allowed script public key in the coinbase's payload
CoinbasePayloadScriptPublicKeyMaxLength = 150
// MaxTxInSequenceNum is the maximum sequence number the sequence field
// of a transaction input can be.
MaxTxInSequenceNum uint64 = math.MaxUint64

View File

@ -0,0 +1,24 @@
package dagconfig
import (
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"time"
)
const (
defaultMaxCoinbasePayloadLength = 150
defaultMaxBlockSize = 1_000_000
defaultMaxBlockParents = 10
defaultMassPerTxByte = 1
defaultMassPerScriptPubKeyByte = 10
defaultMassPerSigOp = 10000
defaultMergeSetSizeLimit = 1000
defaultMaxMassAcceptedByBlock = 10000000
defaultBaseSubsidy = 50 * constants.SompiPerKaspa
defaultCoinbasePayloadScriptPublicKeyMaxLength = 150
defaultGHOSTDAGK = 18
defaultDifficultyAdjustmentWindowSize = 2640
defaultTimestampDeviationTolerance = 132
defaultFinalityDuration = 24 * time.Hour
defaultTargetTimePerBlock = 1 * time.Second
)

View File

@ -5,11 +5,10 @@
package dagconfig
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"math/big"
"time"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/app/appmessage"
@ -45,14 +44,6 @@ var (
devnetPowMax = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 239), bigOne)
)
const (
ghostdagK = 18
difficultyAdjustmentWindowSize = 2640
timestampDeviationTolerance = 132
finalityDuration = 24 * time.Hour
targetTimePerBlock = 1 * time.Second
)
// KType defines the size of GHOSTDAG consensus algorithm K parameter.
type KType uint8
@ -62,7 +53,7 @@ type KType uint8
type Params struct {
// K defines the K parameter for GHOSTDAG consensus algorithm.
// See ghostdag.go for further details.
K KType
K model.KType
// Name defines a human-readable identifier for the network.
Name string
@ -150,6 +141,39 @@ type Params struct {
// SkipProofOfWork indicates whether proof of work should be checked.
SkipProofOfWork bool
// MaxCoinbasePayloadLength is the maximum length in bytes allowed for a block's coinbase's payload
MaxCoinbasePayloadLength uint64
// MaxBlockSize is the maximum size in bytes a block is allowed
MaxBlockSize uint64
// MaxBlockParents is the maximum number of blocks a block is allowed to point to
MaxBlockParents model.KType
// MassPerTxByte is the number of grams that any byte
// adds to a transaction.
MassPerTxByte uint64
// MassPerScriptPubKeyByte is the number of grams that any
// scriptPubKey byte adds to a transaction.
MassPerScriptPubKeyByte uint64
// MassPerSigOp is the number of grams that any
// signature operation adds to a transaction.
MassPerSigOp uint64
// MergeSetSizeLimit is the maximum number of blocks in a block's merge set
MergeSetSizeLimit uint64
// MaxMassAcceptedByBlock is the maximum total transaction mass a block may accept.
MaxMassAcceptedByBlock uint64
// CoinbasePayloadScriptPublicKeyMaxLength is the maximum allowed script public key in the coinbase's payload
CoinbasePayloadScriptPublicKeyMaxLength uint64
// BaseSubsidy is the starting subsidy amount for mined blocks.
BaseSubsidy uint64
}
// NormalizeRPCServerAddress returns addr with the current network default
@ -165,12 +189,12 @@ func (p *Params) FinalityDepth() uint64 {
// PruningDepth returns the pruning duration represented in blocks
func (p *Params) PruningDepth() uint64 {
return 2*p.FinalityDepth() + 4*constants.MergeSetSizeLimit*uint64(p.K) + 2*uint64(p.K) + 2
return 2*p.FinalityDepth() + 4*p.MergeSetSizeLimit*uint64(p.K) + 2*uint64(p.K) + 2
}
// MainnetParams defines the network parameters for the main Kaspa network.
var MainnetParams = Params{
K: ghostdagK,
K: defaultGHOSTDAGK,
Name: "kaspa-mainnet",
Net: appmessage.Mainnet,
RPCPort: "16110",
@ -183,10 +207,10 @@ var MainnetParams = Params{
PowMax: mainPowMax,
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: targetTimePerBlock,
FinalityDuration: finalityDuration,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
TargetTimePerBlock: defaultTargetTimePerBlock,
FinalityDuration: defaultFinalityDuration,
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
TimestampDeviationTolerance: defaultTimestampDeviationTolerance,
// Consensus rule change deployments.
//
@ -212,11 +236,22 @@ var MainnetParams = Params{
EnableNonNativeSubnetworks: false,
DisableDifficultyAdjustment: false,
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
MaxBlockSize: defaultMaxBlockSize,
MaxBlockParents: defaultMaxBlockParents,
MassPerTxByte: defaultMassPerTxByte,
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
MassPerSigOp: defaultMassPerSigOp,
MergeSetSizeLimit: defaultMergeSetSizeLimit,
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
BaseSubsidy: defaultBaseSubsidy,
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
}
// TestnetParams defines the network parameters for the test Kaspa network.
var TestnetParams = Params{
K: ghostdagK,
K: defaultGHOSTDAGK,
Name: "kaspa-testnet",
Net: appmessage.Testnet,
RPCPort: "16210",
@ -229,10 +264,10 @@ var TestnetParams = Params{
PowMax: testnetPowMax,
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: targetTimePerBlock,
FinalityDuration: finalityDuration,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
TargetTimePerBlock: defaultTargetTimePerBlock,
FinalityDuration: defaultFinalityDuration,
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
TimestampDeviationTolerance: defaultTimestampDeviationTolerance,
// Consensus rule change deployments.
//
@ -258,6 +293,17 @@ var TestnetParams = Params{
EnableNonNativeSubnetworks: false,
DisableDifficultyAdjustment: false,
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
MaxBlockSize: defaultMaxBlockSize,
MaxBlockParents: defaultMaxBlockParents,
MassPerTxByte: defaultMassPerTxByte,
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
MassPerSigOp: defaultMassPerSigOp,
MergeSetSizeLimit: defaultMergeSetSizeLimit,
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
BaseSubsidy: defaultBaseSubsidy,
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
}
// SimnetParams defines the network parameters for the simulation test Kaspa
@ -268,7 +314,7 @@ var TestnetParams = Params{
// following normal discovery rules. This is important as otherwise it would
// just turn into another public testnet.
var SimnetParams = Params{
K: ghostdagK,
K: defaultGHOSTDAGK,
Name: "kaspa-simnet",
Net: appmessage.Simnet,
RPCPort: "16510",
@ -283,8 +329,8 @@ var SimnetParams = Params{
SubsidyReductionInterval: 210000,
TargetTimePerBlock: time.Millisecond,
FinalityDuration: time.Minute,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
TimestampDeviationTolerance: defaultTimestampDeviationTolerance,
// Consensus rule change deployments.
//
@ -308,11 +354,22 @@ var SimnetParams = Params{
EnableNonNativeSubnetworks: false,
DisableDifficultyAdjustment: true,
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
MaxBlockSize: defaultMaxBlockSize,
MaxBlockParents: defaultMaxBlockParents,
MassPerTxByte: defaultMassPerTxByte,
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
MassPerSigOp: defaultMassPerSigOp,
MergeSetSizeLimit: defaultMergeSetSizeLimit,
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
BaseSubsidy: defaultBaseSubsidy,
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
}
// DevnetParams defines the network parameters for the development Kaspa network.
var DevnetParams = Params{
K: ghostdagK,
K: defaultGHOSTDAGK,
Name: "kaspa-devnet",
Net: appmessage.Devnet,
RPCPort: "16610",
@ -325,10 +382,10 @@ var DevnetParams = Params{
PowMax: devnetPowMax,
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: targetTimePerBlock,
FinalityDuration: finalityDuration,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
TargetTimePerBlock: defaultTargetTimePerBlock,
FinalityDuration: defaultFinalityDuration,
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
TimestampDeviationTolerance: defaultTimestampDeviationTolerance,
// Consensus rule change deployments.
//
@ -354,6 +411,17 @@ var DevnetParams = Params{
EnableNonNativeSubnetworks: false,
DisableDifficultyAdjustment: false,
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
MaxBlockSize: defaultMaxBlockSize,
MaxBlockParents: defaultMaxBlockParents,
MassPerTxByte: defaultMassPerTxByte,
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
MassPerSigOp: defaultMassPerSigOp,
MergeSetSizeLimit: defaultMergeSetSizeLimit,
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
BaseSubsidy: defaultBaseSubsidy,
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
}
var (

View File

@ -3,7 +3,6 @@ package domain
import (
"github.com/kaspanet/kaspad/domain/consensus"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/kaspanet/kaspad/domain/miningmanager"
infrastructuredatabase "github.com/kaspanet/kaspad/infrastructure/db/database"
@ -37,7 +36,8 @@ func New(dagParams *dagconfig.Params, db infrastructuredatabase.Database) (Domai
}
miningManagerFactory := miningmanager.NewFactory()
miningManager := miningManagerFactory.NewMiningManager(consensusInstance, constants.MaxMassAcceptedByBlock)
miningManager := miningManagerFactory.NewMiningManager(consensusInstance, dagParams.MaxMassAcceptedByBlock,
dagParams.RelayNonStdTxs)
return &domain{
consensus: consensusInstance,

View File

@ -8,14 +8,14 @@ import (
// Factory instantiates new mining managers
type Factory interface {
NewMiningManager(consensus externalapi.Consensus, blockMaxMass uint64) MiningManager
NewMiningManager(consensus externalapi.Consensus, blockMaxMass uint64, acceptNonStd bool) MiningManager
}
type factory struct{}
// NewMiningManager instantiate a new mining manager
func (f *factory) NewMiningManager(consensus externalapi.Consensus, blockMaxMass uint64) MiningManager {
mempool := mempoolpkg.New(consensus)
func (f *factory) NewMiningManager(consensus externalapi.Consensus, blockMaxMass uint64, acceptNonStd bool) MiningManager {
mempool := mempoolpkg.New(consensus, acceptNonStd)
blockTemplateBuilder := blocktemplatebuilder.New(consensus, mempool, blockMaxMass)
return &miningManager{

View File

@ -90,10 +90,10 @@ type mempool struct {
// New returns a new memory pool for validating and storing standalone
// transactions until they are mined into a block.
func New(consensus consensusexternalapi.Consensus) miningmanagermodel.Mempool {
func New(consensus consensusexternalapi.Consensus, acceptNonStd bool) miningmanagermodel.Mempool {
policy := policy{
MaxTxVersion: constants.TransactionVersion,
AcceptNonStd: false,
AcceptNonStd: acceptNonStd,
MaxOrphanTxs: 5,
MaxOrphanTxSize: 100000,
MinRelayTxFee: 1000, // 1 sompi per byte

View File

@ -1,21 +1,53 @@
package config
import (
"encoding/json"
"fmt"
"github.com/jessevdk/go-flags"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/utils/math"
"github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/pkg/errors"
"math/big"
"os"
"time"
)
// NetworkFlags holds the network configuration, that is which network is selected.
type NetworkFlags struct {
Testnet bool `long:"testnet" description:"Use the test network"`
Simnet bool `long:"simnet" description:"Use the simulation test network"`
Devnet bool `long:"devnet" description:"Use the development test network"`
Testnet bool `long:"testnet" description:"Use the test network"`
Simnet bool `long:"simnet" description:"Use the simulation test network"`
Devnet bool `long:"devnet" description:"Use the development test network"`
OverrideDAGParamsFile string `long:"override-dag-params-file" description:"Overrides DAG params (allowed only on devnet)"`
ActiveNetParams *dagconfig.Params
}
type overrideDAGParamsConfig struct {
K *model.KType `json:"k"`
MaxBlockParents *model.KType `json:"maxBlockParents"`
MergeSetSizeLimit *uint64 `json:"mergeSetSizeLimit"`
MaxMassAcceptedByBlock *uint64 `json:"maxMassAcceptedByBlock"`
MaxBlockSize *uint64 `json:"maxBlockSize"`
MaxCoinbasePayloadLength *uint64 `json:"maxCoinbasePayloadLength"`
MassPerTxByte *uint64 `json:"massPerTxByte"`
MassPerScriptPubKeyByte *uint64 `json:"massPerScriptPubKeyByte"`
MassPerSigOp *uint64 `json:"massPerSigOp"`
CoinbasePayloadScriptPublicKeyMaxLength *uint64 `json:"coinbasePayloadScriptPublicKeyMaxLength"`
PowMax *string `json:"powMax"`
BlockCoinbaseMaturity *uint64 `json:"blockCoinbaseMaturity"`
SubsidyReductionInterval *uint64 `json:"subsidyReductionInterval"`
TargetTimePerBlockInMilliSeconds *int64 `json:"targetTimePerBlockInMilliSeconds"`
FinalityDuration *int64 `json:"finalityDuration"`
TimestampDeviationTolerance *uint64 `json:"timestampDeviationTolerance"`
DifficultyAdjustmentWindowSize *uint64 `json:"difficultyAdjustmentWindowSize"`
RelayNonStdTxs *bool `json:"relayNonStdTxs"`
AcceptUnroutable *bool `json:"acceptUnroutable"`
EnableNonNativeSubnetworks *bool `json:"enableNonNativeSubnetworks"`
DisableDifficultyAdjustment *bool `json:"disableDifficultyAdjustment"`
SkipProofOfWork *bool `json:"skipProofOfWork"`
}
// ResolveNetwork parses the network command line argument and sets NetParams accordingly.
// It returns error if more than one network was selected, nil otherwise.
func (networkFlags *NetworkFlags) ResolveNetwork(parser *flags.Parser) error {
@ -58,3 +90,128 @@ func (networkFlags *NetworkFlags) ResolveNetwork(parser *flags.Parser) error {
func (networkFlags *NetworkFlags) NetParams() *dagconfig.Params {
return networkFlags.ActiveNetParams
}
func (networkFlags *NetworkFlags) overrideDAGParams() error {
if networkFlags.OverrideDAGParamsFile == "" {
return nil
}
if !networkFlags.Devnet {
return errors.Errorf("override-dag-params-file is allowed only when using devnet")
}
overrideDAGParamsFile, err := os.Open(networkFlags.OverrideDAGParamsFile)
if err != nil {
return err
}
defer overrideDAGParamsFile.Close()
decoder := json.NewDecoder(overrideDAGParamsFile)
config := &overrideDAGParamsConfig{}
err = decoder.Decode(config)
if err != nil {
return err
}
if config.K != nil {
networkFlags.ActiveNetParams.K = *config.K
}
if config.MaxBlockParents != nil {
networkFlags.ActiveNetParams.MaxBlockParents = *config.MaxBlockParents
}
if config.MergeSetSizeLimit != nil {
networkFlags.ActiveNetParams.MergeSetSizeLimit = *config.MergeSetSizeLimit
}
if config.MaxMassAcceptedByBlock != nil {
networkFlags.ActiveNetParams.MaxMassAcceptedByBlock = *config.MaxMassAcceptedByBlock
}
if config.MaxBlockSize != nil {
networkFlags.ActiveNetParams.MaxBlockSize = *config.MaxBlockSize
}
if config.MaxCoinbasePayloadLength != nil {
networkFlags.ActiveNetParams.MaxCoinbasePayloadLength = *config.MaxCoinbasePayloadLength
}
if config.MassPerTxByte != nil {
networkFlags.ActiveNetParams.MassPerTxByte = *config.MassPerTxByte
}
if config.MassPerScriptPubKeyByte != nil {
networkFlags.ActiveNetParams.MassPerScriptPubKeyByte = *config.MassPerScriptPubKeyByte
}
if config.MassPerSigOp != nil {
networkFlags.ActiveNetParams.MassPerSigOp = *config.MassPerSigOp
}
if config.CoinbasePayloadScriptPublicKeyMaxLength != nil {
networkFlags.ActiveNetParams.CoinbasePayloadScriptPublicKeyMaxLength = *config.CoinbasePayloadScriptPublicKeyMaxLength
}
if config.PowMax != nil {
powMax, ok := big.NewInt(0).SetString(*config.PowMax, 16)
if !ok {
return errors.Errorf("couldn't convert %s to big int", *config.PowMax)
}
genesisTarget := math.CompactToBig(networkFlags.ActiveNetParams.GenesisBlock.Header.Bits)
if powMax.Cmp(genesisTarget) > 0 {
return errors.Errorf("powMax (%s) is smaller than genesis's target (%s)", powMax.Text(16),
genesisTarget.Text(16))
}
networkFlags.ActiveNetParams.PowMax = powMax
}
if config.BlockCoinbaseMaturity != nil {
networkFlags.ActiveNetParams.BlockCoinbaseMaturity = *config.BlockCoinbaseMaturity
}
if config.SubsidyReductionInterval != nil {
networkFlags.ActiveNetParams.SubsidyReductionInterval = *config.SubsidyReductionInterval
}
if config.TargetTimePerBlockInMilliSeconds != nil {
networkFlags.ActiveNetParams.TargetTimePerBlock = time.Duration(*config.TargetTimePerBlockInMilliSeconds) *
time.Millisecond
}
if config.FinalityDuration != nil {
networkFlags.ActiveNetParams.FinalityDuration = time.Duration(*config.FinalityDuration) * time.Millisecond
}
if config.TimestampDeviationTolerance != nil {
networkFlags.ActiveNetParams.TimestampDeviationTolerance = *config.TimestampDeviationTolerance
}
if config.DifficultyAdjustmentWindowSize != nil {
networkFlags.ActiveNetParams.DifficultyAdjustmentWindowSize = *config.DifficultyAdjustmentWindowSize
}
if config.TimestampDeviationTolerance != nil {
networkFlags.ActiveNetParams.TimestampDeviationTolerance = *config.TimestampDeviationTolerance
}
if config.RelayNonStdTxs != nil {
networkFlags.ActiveNetParams.RelayNonStdTxs = *config.RelayNonStdTxs
}
if config.AcceptUnroutable != nil {
networkFlags.ActiveNetParams.AcceptUnroutable = *config.AcceptUnroutable
}
if config.EnableNonNativeSubnetworks != nil {
networkFlags.ActiveNetParams.EnableNonNativeSubnetworks = *config.EnableNonNativeSubnetworks
}
if config.SkipProofOfWork != nil {
networkFlags.ActiveNetParams.SkipProofOfWork = *config.SkipProofOfWork
}
return nil
}