chaincfg/blockchain: Parameterize more chain consts. (#732)
This moves several of the chain constants to the Params struct in the chaincfg package which is intended for that purpose. This is mostly a backport of the same modifications made in Decred along with a few additional things cleaned up. The following is an overview of the changes: - Comment all fields in the Params struct definition - Add locals to BlockChain instance for the calculated values based on the provided chain params - Rename the following param fields: - SubsidyHalvingInterval -> SubsidyReductionInterval - ResetMinDifficulty -> ReduceMinDifficulty - Add new Param fields: - CoinbaseMaturity - TargetTimePerBlock - TargetTimespan - BlocksPerRetarget - RetargetAdjustmentFactor - MinDiffReductionTime
This commit is contained in:
parent
bd4e64d1d4
commit
a7b35d9f9e
11 changed files with 183 additions and 123 deletions
|
@ -24,12 +24,6 @@ const (
|
|||
// maxOrphanBlocks is the maximum number of orphan blocks that can be
|
||||
// queued.
|
||||
maxOrphanBlocks = 100
|
||||
|
||||
// minMemoryNodes is the minimum number of consecutive nodes needed
|
||||
// in memory in order to perform all necessary validation. It is used
|
||||
// to determine when it's safe to prune nodes from memory without
|
||||
// causing constant dynamic reloading.
|
||||
minMemoryNodes = BlocksPerRetarget
|
||||
)
|
||||
|
||||
// blockNode represents a block within the block chain and is primarily used to
|
||||
|
@ -170,6 +164,22 @@ type BlockChain struct {
|
|||
sigCache *txscript.SigCache
|
||||
indexManager IndexManager
|
||||
|
||||
// The following fields are calculated based upon the provided chain
|
||||
// parameters. They are also set when the instance is created and
|
||||
// can't be changed afterwards, so there is no need to protect them with
|
||||
// a separate mutex.
|
||||
//
|
||||
// minMemoryNodes is the minimum number of consecutive nodes needed
|
||||
// in memory in order to perform all necessary validation. It is used
|
||||
// to determine when it's safe to prune nodes from memory without
|
||||
// causing constant dynamic reloading. This is typically the same value
|
||||
// as blocksPerRetarget, but it is separated here for tweakability and
|
||||
// testability.
|
||||
minRetargetTimespan int64 // target timespan / adjustment factor
|
||||
maxRetargetTimespan int64 // target timespan * adjustment factor
|
||||
blocksPerRetarget int32 // target timespan / target time per block
|
||||
minMemoryNodes int32
|
||||
|
||||
// chainLock protects concurrent access to the vast majority of the
|
||||
// fields in this struct below this point.
|
||||
chainLock sync.RWMutex
|
||||
|
@ -553,7 +563,7 @@ func (b *BlockChain) pruneBlockNodes() error {
|
|||
// the latter loads the node and the goal is to find nodes still in
|
||||
// memory that can be pruned.
|
||||
newRootNode := b.bestNode
|
||||
for i := int32(0); i < minMemoryNodes-1 && newRootNode != nil; i++ {
|
||||
for i := int32(0); i < b.minMemoryNodes-1 && newRootNode != nil; i++ {
|
||||
newRootNode = newRootNode.parent
|
||||
}
|
||||
|
||||
|
@ -1454,6 +1464,9 @@ func New(config *Config) (*BlockChain, error) {
|
|||
}
|
||||
}
|
||||
|
||||
targetTimespan := int64(params.TargetTimespan)
|
||||
targetTimePerBlock := int64(params.TargetTimePerBlock)
|
||||
adjustmentFactor := params.RetargetAdjustmentFactor
|
||||
b := BlockChain{
|
||||
checkpointsByHeight: checkpointsByHeight,
|
||||
db: config.DB,
|
||||
|
@ -1462,6 +1475,10 @@ func New(config *Config) (*BlockChain, error) {
|
|||
notifications: config.Notifications,
|
||||
sigCache: config.SigCache,
|
||||
indexManager: config.IndexManager,
|
||||
minRetargetTimespan: targetTimespan / adjustmentFactor,
|
||||
maxRetargetTimespan: targetTimespan * adjustmentFactor,
|
||||
blocksPerRetarget: int32(targetTimespan / targetTimePerBlock),
|
||||
minMemoryNodes: int32(targetTimespan / targetTimePerBlock),
|
||||
bestNode: nil,
|
||||
index: make(map[chainhash.Hash]*blockNode),
|
||||
depNodes: make(map[chainhash.Hash][]*blockNode),
|
||||
|
|
|
@ -46,7 +46,7 @@ func TestHaveBlock(t *testing.T) {
|
|||
// Since we're not dealing with the real block chain, disable
|
||||
// checkpoints and set the coinbase maturity to 1.
|
||||
chain.DisableCheckpoints(true)
|
||||
blockchain.TstSetCoinbaseMaturity(1)
|
||||
chain.TstSetCoinbaseMaturity(1)
|
||||
|
||||
for i := 1; i < len(blocks); i++ {
|
||||
isOrphan, err := chain.ProcessBlock(blocks[i], blockchain.BFNone)
|
||||
|
|
|
@ -107,10 +107,14 @@ func chainSetup(dbName string) (*blockchain.BlockChain, func(), error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Copy the chain params to ensure any modifications the tests do to
|
||||
// the chain parameters do not affect the global instance.
|
||||
mainNetParams := chaincfg.MainNetParams
|
||||
|
||||
// Create the main chain instance.
|
||||
chain, err := blockchain.New(&blockchain.Config{
|
||||
DB: db,
|
||||
ChainParams: &chaincfg.MainNetParams,
|
||||
ChainParams: &mainNetParams,
|
||||
TimeSource: blockchain.NewMedianTime(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -11,37 +11,6 @@ import (
|
|||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
const (
|
||||
// targetTimespan is the desired amount of time that should elapse
|
||||
// before block difficulty requirement is examined to determine how
|
||||
// it should be changed in order to maintain the desired block
|
||||
// generation rate.
|
||||
targetTimespan = time.Hour * 24 * 14
|
||||
|
||||
// targetSpacing is the desired amount of time to generate each block.
|
||||
targetSpacing = time.Minute * 10
|
||||
|
||||
// BlocksPerRetarget is the number of blocks between each difficulty
|
||||
// retarget. It is calculated based on the desired block generation
|
||||
// rate.
|
||||
BlocksPerRetarget = int32(targetTimespan / targetSpacing)
|
||||
|
||||
// retargetAdjustmentFactor is the adjustment factor used to limit
|
||||
// the minimum and maximum amount of adjustment that can occur between
|
||||
// difficulty retargets.
|
||||
retargetAdjustmentFactor = 4
|
||||
|
||||
// minRetargetTimespan is the minimum amount of adjustment that can
|
||||
// occur between difficulty retargets. It equates to 25% of the
|
||||
// previous difficulty.
|
||||
minRetargetTimespan = int64(targetTimespan / retargetAdjustmentFactor)
|
||||
|
||||
// maxRetargetTimespan is the maximum amount of adjustment that can
|
||||
// occur between difficulty retargets. It equates to 400% of the
|
||||
// previous difficulty.
|
||||
maxRetargetTimespan = int64(targetTimespan * retargetAdjustmentFactor)
|
||||
)
|
||||
|
||||
var (
|
||||
// bigOne is 1 represented as a big.Int. It is defined here to avoid
|
||||
// the overhead of creating it multiple times.
|
||||
|
@ -190,13 +159,13 @@ func CalcWork(bits uint32) *big.Int {
|
|||
func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 {
|
||||
// Convert types used in the calculations below.
|
||||
durationVal := int64(duration)
|
||||
adjustmentFactor := big.NewInt(retargetAdjustmentFactor)
|
||||
adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor)
|
||||
|
||||
// The test network rules allow minimum difficulty blocks after more
|
||||
// than twice the desired amount of time needed to generate a block has
|
||||
// elapsed.
|
||||
if b.chainParams.ResetMinDifficulty {
|
||||
if durationVal > int64(targetSpacing)*2 {
|
||||
if b.chainParams.ReduceMinDifficulty {
|
||||
if durationVal > int64(b.chainParams.MinDiffReductionTime) {
|
||||
return b.chainParams.PowLimitBits
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +177,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration)
|
|||
newTarget := CompactToBig(bits)
|
||||
for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 {
|
||||
newTarget.Mul(newTarget, adjustmentFactor)
|
||||
durationVal -= maxRetargetTimespan
|
||||
durationVal -= b.maxRetargetTimespan
|
||||
}
|
||||
|
||||
// Limit new value to the proof of work limit.
|
||||
|
@ -227,7 +196,7 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er
|
|||
// Search backwards through the chain for the last block without
|
||||
// the special rule applied.
|
||||
iterNode := startNode
|
||||
for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 &&
|
||||
for iterNode != nil && iterNode.height%b.blocksPerRetarget != 0 &&
|
||||
iterNode.bits == b.chainParams.PowLimitBits {
|
||||
|
||||
// Get the previous block node. This function is used over
|
||||
|
@ -267,15 +236,15 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim
|
|||
|
||||
// Return the previous block's difficulty requirements if this block
|
||||
// is not at a difficulty retarget interval.
|
||||
if (lastNode.height+1)%BlocksPerRetarget != 0 {
|
||||
// The test network rules allow minimum difficulty blocks after
|
||||
// more than twice the desired amount of time needed to generate
|
||||
// a block has elapsed.
|
||||
if b.chainParams.ResetMinDifficulty {
|
||||
// Return minimum difficulty when more than twice the
|
||||
// desired amount of time needed to generate a block has
|
||||
// elapsed.
|
||||
allowMinTime := lastNode.timestamp.Add(targetSpacing * 2)
|
||||
if (lastNode.height+1)%b.blocksPerRetarget != 0 {
|
||||
// For networks that support it, allow special reduction of the
|
||||
// required difficulty once too much time has elapsed without
|
||||
// mining a block.
|
||||
if b.chainParams.ReduceMinDifficulty {
|
||||
// Return minimum difficulty when more than the desired
|
||||
// amount of time has elapsed without mining a block.
|
||||
reductionTime := b.chainParams.MinDiffReductionTime
|
||||
allowMinTime := lastNode.timestamp.Add(reductionTime)
|
||||
if newBlockTime.After(allowMinTime) {
|
||||
return b.chainParams.PowLimitBits, nil
|
||||
}
|
||||
|
@ -298,7 +267,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim
|
|||
// Get the block node at the previous retarget (targetTimespan days
|
||||
// worth of blocks).
|
||||
firstNode := lastNode
|
||||
for i := int32(0); i < BlocksPerRetarget-1 && firstNode != nil; i++ {
|
||||
for i := int32(0); i < b.blocksPerRetarget-1 && firstNode != nil; i++ {
|
||||
// Get the previous block node. This function is used over
|
||||
// simply accessing firstNode.parent directly as it will
|
||||
// dynamically create previous block nodes as needed. This
|
||||
|
@ -319,10 +288,10 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim
|
|||
// difficulty.
|
||||
actualTimespan := lastNode.timestamp.UnixNano() - firstNode.timestamp.UnixNano()
|
||||
adjustedTimespan := actualTimespan
|
||||
if actualTimespan < minRetargetTimespan {
|
||||
adjustedTimespan = minRetargetTimespan
|
||||
} else if actualTimespan > maxRetargetTimespan {
|
||||
adjustedTimespan = maxRetargetTimespan
|
||||
if actualTimespan < b.minRetargetTimespan {
|
||||
adjustedTimespan = b.minRetargetTimespan
|
||||
} else if actualTimespan > b.maxRetargetTimespan {
|
||||
adjustedTimespan = b.maxRetargetTimespan
|
||||
}
|
||||
|
||||
// Calculate new target difficulty as:
|
||||
|
@ -332,7 +301,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim
|
|||
// result.
|
||||
oldTarget := CompactToBig(lastNode.bits)
|
||||
newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))
|
||||
newTarget.Div(newTarget, big.NewInt(int64(targetTimespan)))
|
||||
newTarget.Div(newTarget, big.NewInt(int64(b.chainParams.TargetTimespan)))
|
||||
|
||||
// Limit new value to the proof of work limit.
|
||||
if newTarget.Cmp(b.chainParams.PowLimit) > 0 {
|
||||
|
@ -349,7 +318,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim
|
|||
log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits))
|
||||
log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v",
|
||||
time.Duration(actualTimespan), time.Duration(adjustedTimespan),
|
||||
targetTimespan)
|
||||
b.chainParams.TargetTimespan)
|
||||
|
||||
return newTargetBits, nil
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
|
||||
// TstSetCoinbaseMaturity makes the ability to set the coinbase maturity
|
||||
// available to the test package.
|
||||
func TstSetCoinbaseMaturity(maturity int32) {
|
||||
coinbaseMaturity = maturity
|
||||
func (b *BlockChain) TstSetCoinbaseMaturity(maturity uint16) {
|
||||
b.chainParams.CoinbaseMaturity = maturity
|
||||
}
|
||||
|
||||
// TstTimeSorter makes the internal timeSorter type available to the test
|
||||
|
|
|
@ -56,7 +56,7 @@ func TestReorganization(t *testing.T) {
|
|||
// Since we're not dealing with the real block chain, disable
|
||||
// checkpoints and set the coinbase maturity to 1.
|
||||
chain.DisableCheckpoints(true)
|
||||
blockchain.TstSetCoinbaseMaturity(1)
|
||||
chain.TstSetCoinbaseMaturity(1)
|
||||
|
||||
expectedOrphans := map[int]struct{}{5: {}, 6: {}}
|
||||
for i := 1; i < len(blocks); i++ {
|
||||
|
|
|
@ -45,18 +45,9 @@ const (
|
|||
// baseSubsidy is the starting subsidy amount for mined blocks. This
|
||||
// value is halved every SubsidyHalvingInterval blocks.
|
||||
baseSubsidy = 50 * btcutil.SatoshiPerBitcoin
|
||||
|
||||
// CoinbaseMaturity is the number of blocks required before newly
|
||||
// mined bitcoins (coinbase transactions) can be spent.
|
||||
CoinbaseMaturity = 100
|
||||
)
|
||||
|
||||
var (
|
||||
// coinbaseMaturity is the internal variable used for validating the
|
||||
// spending of coinbase outputs. A variable rather than the exported
|
||||
// constant is used because the tests need the ability to modify it.
|
||||
coinbaseMaturity = int32(CoinbaseMaturity)
|
||||
|
||||
// zeroHash is the zero value for a chainhash.Hash and is defined as
|
||||
// a package level variable to avoid the need to create a new instance
|
||||
// every time a check is needed.
|
||||
|
@ -182,18 +173,18 @@ func isBIP0030Node(node *blockNode) bool {
|
|||
// newly generated blocks awards as well as validating the coinbase for blocks
|
||||
// has the expected value.
|
||||
//
|
||||
// The subsidy is halved every SubsidyHalvingInterval blocks. Mathematically
|
||||
// this is: baseSubsidy / 2^(height/subsidyHalvingInterval)
|
||||
// The subsidy is halved every SubsidyReductionInterval blocks. Mathematically
|
||||
// this is: baseSubsidy / 2^(height/SubsidyReductionInterval)
|
||||
//
|
||||
// At the target block generation rate for the main network, this is
|
||||
// approximately every 4 years.
|
||||
func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params) int64 {
|
||||
if chainParams.SubsidyHalvingInterval == 0 {
|
||||
if chainParams.SubsidyReductionInterval == 0 {
|
||||
return baseSubsidy
|
||||
}
|
||||
|
||||
// Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval)
|
||||
return baseSubsidy >> uint(height/chainParams.SubsidyHalvingInterval)
|
||||
return baseSubsidy >> uint(height/chainParams.SubsidyReductionInterval)
|
||||
}
|
||||
|
||||
// CheckTransactionSanity performs some preliminary checks on a transaction to
|
||||
|
@ -833,7 +824,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *U
|
|||
//
|
||||
// NOTE: The transaction MUST have already been sanity checked with the
|
||||
// CheckTransactionSanity function prior to calling this function.
|
||||
func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, utxoView *UtxoViewpoint) (int64, error) {
|
||||
func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, utxoView *UtxoViewpoint, chainParams *chaincfg.Params) (int64, error) {
|
||||
// Coinbase transactions have no inputs.
|
||||
if IsCoinBase(tx) {
|
||||
return 0, nil
|
||||
|
@ -857,6 +848,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, utxoView *UtxoViewpo
|
|||
if utxoEntry.IsCoinBase() {
|
||||
originHeight := int32(utxoEntry.BlockHeight())
|
||||
blocksSincePrev := txHeight - originHeight
|
||||
coinbaseMaturity := int32(chainParams.CoinbaseMaturity)
|
||||
if blocksSincePrev < coinbaseMaturity {
|
||||
str := fmt.Sprintf("tried to spend coinbase "+
|
||||
"transaction %v from height %v at "+
|
||||
|
@ -1050,7 +1042,8 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
|
|||
// bounds.
|
||||
var totalFees int64
|
||||
for _, tx := range transactions {
|
||||
txFee, err := CheckTransactionInputs(tx, node.height, view)
|
||||
txFee, err := CheckTransactionInputs(tx, node.height, view,
|
||||
b.chainParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package chaincfg
|
|||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
|
@ -53,19 +54,70 @@ type Checkpoint struct {
|
|||
// used by Bitcoin applications to differentiate networks as well as addresses
|
||||
// and keys for one network from those intended for use on another network.
|
||||
type Params struct {
|
||||
Name string
|
||||
Net wire.BitcoinNet
|
||||
DefaultPort string
|
||||
DNSSeeds []string
|
||||
// Name defines a human-readable identifier for the network.
|
||||
Name string
|
||||
|
||||
// Chain parameters
|
||||
GenesisBlock *wire.MsgBlock
|
||||
GenesisHash *chainhash.Hash
|
||||
PowLimit *big.Int
|
||||
PowLimitBits uint32
|
||||
SubsidyHalvingInterval int32
|
||||
ResetMinDifficulty bool
|
||||
GenerateSupported bool
|
||||
// Net defines the magic bytes used to identify the network.
|
||||
Net wire.BitcoinNet
|
||||
|
||||
// DefaultPort defines the default peer-to-peer port for the network.
|
||||
DefaultPort string
|
||||
|
||||
// DNSSeeds defines a list of DNS seeds for the network that are used
|
||||
// as one method to discover peers.
|
||||
DNSSeeds []string
|
||||
|
||||
// GenesisBlock defines the first block of the chain.
|
||||
GenesisBlock *wire.MsgBlock
|
||||
|
||||
// GenesisHash is the starting block hash.
|
||||
GenesisHash *chainhash.Hash
|
||||
|
||||
// PowLimit defines the highest allowed proof of work value for a block
|
||||
// as a uint256.
|
||||
PowLimit *big.Int
|
||||
|
||||
// PowLimitBits defines the highest allowed proof of work value for a
|
||||
// block in compact form.
|
||||
PowLimitBits uint32
|
||||
|
||||
// CoinbaseMaturity is the number of blocks required before newly mined
|
||||
// coins (coinbase transactions) can be spent.
|
||||
CoinbaseMaturity uint16
|
||||
|
||||
// SubsidyReductionInterval is the interval of blocks before the subsidy
|
||||
// is reduced.
|
||||
SubsidyReductionInterval int32
|
||||
|
||||
// TargetTimespan is the desired amount of time that should elapse
|
||||
// before the block difficulty requirement is examined to determine how
|
||||
// it should be changed in order to maintain the desired block
|
||||
// generation rate.
|
||||
TargetTimespan time.Duration
|
||||
|
||||
// TargetTimePerBlock is the desired amount of time to generate each
|
||||
// block.
|
||||
TargetTimePerBlock time.Duration
|
||||
|
||||
// RetargetAdjustmentFactor is the adjustment factor used to limit
|
||||
// the minimum and maximum amount of adjustment that can occur between
|
||||
// difficulty retargets.
|
||||
RetargetAdjustmentFactor int64
|
||||
|
||||
// ReduceMinDifficulty defines whether the network should reduce the
|
||||
// minimum required difficulty after a long enough period of time has
|
||||
// passed without finding a block. This is really only useful for test
|
||||
// networks and should not be set on a main network.
|
||||
ReduceMinDifficulty bool
|
||||
|
||||
// MinDiffReductionTime is the amount of time after which the minimum
|
||||
// required difficulty should be reduced when a block hasn't been found.
|
||||
//
|
||||
// NOTE: This only applies if ReduceMinDifficulty is true.
|
||||
MinDiffReductionTime time.Duration
|
||||
|
||||
// GenerateSupported specifies whether or not CPU mining is allowed.
|
||||
GenerateSupported bool
|
||||
|
||||
// Checkpoints ordered from oldest to newest.
|
||||
Checkpoints []Checkpoint
|
||||
|
@ -114,13 +166,18 @@ var MainNetParams = Params{
|
|||
},
|
||||
|
||||
// Chain parameters
|
||||
GenesisBlock: &genesisBlock,
|
||||
GenesisHash: &genesisHash,
|
||||
PowLimit: mainPowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
SubsidyHalvingInterval: 210000,
|
||||
ResetMinDifficulty: false,
|
||||
GenerateSupported: false,
|
||||
GenesisBlock: &genesisBlock,
|
||||
GenesisHash: &genesisHash,
|
||||
PowLimit: mainPowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
RetargetAdjustmentFactor: 4, // 25% less, 400% more
|
||||
ReduceMinDifficulty: false,
|
||||
MinDiffReductionTime: 0,
|
||||
GenerateSupported: false,
|
||||
|
||||
// Checkpoints ordered from oldest to newest.
|
||||
Checkpoints: []Checkpoint{
|
||||
|
@ -181,13 +238,18 @@ var RegressionNetParams = Params{
|
|||
DNSSeeds: []string{},
|
||||
|
||||
// Chain parameters
|
||||
GenesisBlock: ®TestGenesisBlock,
|
||||
GenesisHash: ®TestGenesisHash,
|
||||
PowLimit: regressionPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
SubsidyHalvingInterval: 150,
|
||||
ResetMinDifficulty: true,
|
||||
GenerateSupported: true,
|
||||
GenesisBlock: ®TestGenesisBlock,
|
||||
GenesisHash: ®TestGenesisHash,
|
||||
PowLimit: regressionPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 150,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
RetargetAdjustmentFactor: 4, // 25% less, 400% more
|
||||
ReduceMinDifficulty: true,
|
||||
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
|
||||
GenerateSupported: true,
|
||||
|
||||
// Checkpoints ordered from oldest to newest.
|
||||
Checkpoints: nil,
|
||||
|
@ -233,13 +295,18 @@ var TestNet3Params = Params{
|
|||
},
|
||||
|
||||
// Chain parameters
|
||||
GenesisBlock: &testNet3GenesisBlock,
|
||||
GenesisHash: &testNet3GenesisHash,
|
||||
PowLimit: testNet3PowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
SubsidyHalvingInterval: 210000,
|
||||
ResetMinDifficulty: true,
|
||||
GenerateSupported: false,
|
||||
GenesisBlock: &testNet3GenesisBlock,
|
||||
GenesisHash: &testNet3GenesisHash,
|
||||
PowLimit: testNet3PowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
RetargetAdjustmentFactor: 4, // 25% less, 400% more
|
||||
ReduceMinDifficulty: true,
|
||||
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
|
||||
GenerateSupported: false,
|
||||
|
||||
// Checkpoints ordered from oldest to newest.
|
||||
Checkpoints: []Checkpoint{
|
||||
|
@ -287,13 +354,18 @@ var SimNetParams = Params{
|
|||
DNSSeeds: []string{}, // NOTE: There must NOT be any seeds.
|
||||
|
||||
// Chain parameters
|
||||
GenesisBlock: &simNetGenesisBlock,
|
||||
GenesisHash: &simNetGenesisHash,
|
||||
PowLimit: simNetPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
SubsidyHalvingInterval: 210000,
|
||||
ResetMinDifficulty: true,
|
||||
GenerateSupported: true,
|
||||
GenesisBlock: &simNetGenesisBlock,
|
||||
GenesisHash: &simNetGenesisHash,
|
||||
PowLimit: simNetPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
RetargetAdjustmentFactor: 4, // 25% less, 400% more
|
||||
ReduceMinDifficulty: true,
|
||||
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
|
||||
GenerateSupported: true,
|
||||
|
||||
// Checkpoints ordered from oldest to newest.
|
||||
Checkpoints: nil,
|
||||
|
|
|
@ -596,7 +596,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
|||
// Also returns the fees associated with the transaction which will be
|
||||
// used later.
|
||||
txFee, err := blockchain.CheckTransactionInputs(tx, nextBlockHeight,
|
||||
utxoView)
|
||||
utxoView, activeNetParams.Params)
|
||||
if err != nil {
|
||||
if cerr, ok := err.(blockchain.RuleError); ok {
|
||||
return nil, chainRuleError(cerr)
|
||||
|
|
|
@ -651,7 +651,7 @@ mempoolLoop:
|
|||
// Ensure the transaction inputs pass all of the necessary
|
||||
// preconditions before allowing it to be added to the block.
|
||||
_, err = blockchain.CheckTransactionInputs(tx, nextBlockHeight,
|
||||
blockUtxos)
|
||||
blockUtxos, activeNetParams.Params)
|
||||
if err != nil {
|
||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||
"CheckTransactionInputs: %v", tx.Hash(), err)
|
||||
|
@ -781,7 +781,7 @@ func UpdateBlockTime(msgBlock *wire.MsgBlock, bManager *blockManager) error {
|
|||
|
||||
// If running on a network that requires recalculating the difficulty,
|
||||
// do so now.
|
||||
if activeNetParams.ResetMinDifficulty {
|
||||
if activeNetParams.ReduceMinDifficulty {
|
||||
difficulty, err := bManager.chain.CalcNextRequiredDifficulty(
|
||||
newTimestamp)
|
||||
if err != nil {
|
||||
|
|
|
@ -2104,6 +2104,11 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru
|
|||
endHeight = best.Height
|
||||
}
|
||||
|
||||
// Calculate the number of blocks per retarget interval based on the
|
||||
// chain parameters.
|
||||
blocksPerRetarget := int32(s.server.chainParams.TargetTimespan /
|
||||
s.server.chainParams.TargetTimePerBlock)
|
||||
|
||||
// Calculate the starting block height based on the passed number of
|
||||
// blocks. When the passed value is negative, use the last block the
|
||||
// difficulty changed as the starting height. Also make sure the
|
||||
|
@ -2114,7 +2119,7 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru
|
|||
}
|
||||
var startHeight int32
|
||||
if numBlocks <= 0 {
|
||||
startHeight = endHeight - ((endHeight % blockchain.BlocksPerRetarget) + 1)
|
||||
startHeight = endHeight - ((endHeight % blocksPerRetarget) + 1)
|
||||
} else {
|
||||
startHeight = endHeight - numBlocks
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue