mining+config: modify GBT mining to limit by weight, add witness commitment
This commit modifies the existing block selection logic to limit preferentially by weight instead of serialized block size, and also to adhere to the new sig-op cost limits which are weighted according to the witness discount.
This commit is contained in:
parent
8b130ec4ea
commit
1244c45b88
5 changed files with 172 additions and 72 deletions
|
@ -1473,6 +1473,7 @@ func newBlockManager(s *server, indexManager blockchain.IndexManager) (*blockMan
|
|||
Notifications: bm.handleNotifyMsg,
|
||||
SigCache: s.sigCache,
|
||||
IndexManager: indexManager,
|
||||
HashCache: s.hashCache,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
49
config.go
49
config.go
|
@ -20,13 +20,13 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/connmgr"
|
||||
"github.com/btcsuite/btcd/database"
|
||||
_ "github.com/btcsuite/btcd/database/ffldb"
|
||||
"github.com/btcsuite/btcd/mempool"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/go-socks/socks"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
|
@ -49,8 +49,12 @@ const (
|
|||
defaultFreeTxRelayLimit = 15.0
|
||||
defaultBlockMinSize = 0
|
||||
defaultBlockMaxSize = 750000
|
||||
defaultBlockMinWeight = 0
|
||||
defaultBlockMaxWeight = 3000000
|
||||
blockMaxSizeMin = 1000
|
||||
blockMaxSizeMax = wire.MaxBlockPayload - 1000
|
||||
blockMaxSizeMax = blockchain.MaxBlockBaseSize - 1000
|
||||
blockMaxWeightMin = 4000
|
||||
blockMaxWeightMax = blockchain.MaxBlockWeight - 4000
|
||||
defaultGenerate = false
|
||||
defaultMaxOrphanTransactions = 100
|
||||
defaultMaxOrphanTxSize = 100000
|
||||
|
@ -140,6 +144,8 @@ type config struct {
|
|||
MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"`
|
||||
BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"`
|
||||
BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"`
|
||||
BlockMinWeight uint32 `long:"blockminweight" description:"Mininum block weight to be used when creating a block"`
|
||||
BlockMaxWeight uint32 `long:"blockmaxweight" description:"Maximum block weight to be used when creating a block"`
|
||||
BlockPrioritySize uint32 `long:"blockprioritysize" description:"Size in bytes for high-priority/low-fee transactions when creating a block"`
|
||||
UserAgentComments []string `long:"uacomment" description:"Comment to add to the user agent -- See BIP 14 for more information."`
|
||||
NoPeerBloomFilters bool `long:"nopeerbloomfilters" description:"Disable bloom filtering support"`
|
||||
|
@ -407,6 +413,8 @@ func loadConfig() (*config, []string, error) {
|
|||
FreeTxRelayLimit: defaultFreeTxRelayLimit,
|
||||
BlockMinSize: defaultBlockMinSize,
|
||||
BlockMaxSize: defaultBlockMaxSize,
|
||||
BlockMinWeight: defaultBlockMinWeight,
|
||||
BlockMaxWeight: defaultBlockMaxWeight,
|
||||
BlockPrioritySize: mempool.DefaultBlockPrioritySize,
|
||||
MaxOrphanTxs: defaultMaxOrphanTransactions,
|
||||
SigCacheMaxSize: defaultSigCacheMaxSize,
|
||||
|
@ -531,8 +539,8 @@ func loadConfig() (*config, []string, error) {
|
|||
cfg.DisableDNSSeed = true
|
||||
}
|
||||
if numNets > 1 {
|
||||
str := "%s: The testnet, regtest, and simnet params can't be " +
|
||||
"used together -- choose one of the three"
|
||||
str := "%s: The testnet, regtest, segnet, and simnet params " +
|
||||
"can't be used together -- choose one of the four"
|
||||
err := fmt.Errorf(str, funcName)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
|
@ -723,7 +731,20 @@ func loadConfig() (*config, []string, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Limit the max orphan count to a sane value.
|
||||
// Limit the max block weight to a sane value.
|
||||
if cfg.BlockMaxWeight < blockMaxWeightMin ||
|
||||
cfg.BlockMaxWeight > blockMaxWeightMax {
|
||||
|
||||
str := "%s: The blockmaxweight option must be in between %d " +
|
||||
"and %d -- parsed [%d]"
|
||||
err := fmt.Errorf(str, funcName, blockMaxWeightMin,
|
||||
blockMaxWeightMax, cfg.BlockMaxWeight)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Limit the max orphan count to a sane vlue.
|
||||
if cfg.MaxOrphanTxs < 0 {
|
||||
str := "%s: The maxorphantx option may not be less than 0 " +
|
||||
"-- parsed [%d]"
|
||||
|
@ -736,6 +757,24 @@ func loadConfig() (*config, []string, error) {
|
|||
// Limit the block priority and minimum block sizes to max block size.
|
||||
cfg.BlockPrioritySize = minUint32(cfg.BlockPrioritySize, cfg.BlockMaxSize)
|
||||
cfg.BlockMinSize = minUint32(cfg.BlockMinSize, cfg.BlockMaxSize)
|
||||
cfg.BlockMinWeight = minUint32(cfg.BlockMinWeight, cfg.BlockMaxWeight)
|
||||
|
||||
switch {
|
||||
// If the max block size isn't set, but the max weight is, then we'll
|
||||
// set the limit for the max block size to a safe limit so weight takes
|
||||
// precedence.
|
||||
case cfg.BlockMaxSize == defaultBlockMaxSize &&
|
||||
cfg.BlockMaxWeight != defaultBlockMaxWeight:
|
||||
|
||||
cfg.BlockMaxSize = blockchain.MaxBlockBaseSize - 1000
|
||||
|
||||
// If the max block weight isn't set, but the block size is, then we'll
|
||||
// scale the set weight accordingly based on the max block size value.
|
||||
case cfg.BlockMaxSize != defaultBlockMaxSize &&
|
||||
cfg.BlockMaxWeight == defaultBlockMaxWeight:
|
||||
|
||||
cfg.BlockMaxWeight = cfg.BlockMaxSize * blockchain.WitnessScaleFactor
|
||||
}
|
||||
|
||||
// Look for illegal characters in the user agent comments.
|
||||
for _, uaComment := range cfg.UserAgentComments {
|
||||
|
|
172
mining/mining.go
172
mining/mining.go
|
@ -197,9 +197,9 @@ type BlockTemplate struct {
|
|||
// sum of the fees of all other transactions.
|
||||
Fees []int64
|
||||
|
||||
// SigOpCounts contains the number of signature operations each
|
||||
// SigOpCosts contains the number of signature operations each
|
||||
// transaction in the generated template performs.
|
||||
SigOpCounts []int64
|
||||
SigOpCosts []int64
|
||||
|
||||
// Height is the height at which the block template connects to the main
|
||||
// chain.
|
||||
|
@ -210,6 +210,12 @@ type BlockTemplate struct {
|
|||
// NewBlockTemplate for details on which this can be useful to generate
|
||||
// templates without a coinbase payment address.
|
||||
ValidPayAddress bool
|
||||
|
||||
// WitnessCommitment is a commitment to the witness data (if any)
|
||||
// within the block. This field will only be populted once segregated
|
||||
// witness has been activated, and the block contains a transaction
|
||||
// which has witness data.
|
||||
WitnessCommitment []byte
|
||||
}
|
||||
|
||||
// mergeUtxoView adds all of the entries in view to viewA. The result is that
|
||||
|
@ -347,6 +353,7 @@ type BlkTmplGenerator struct {
|
|||
chain *blockchain.BlockChain
|
||||
timeSource blockchain.MedianTimeSource
|
||||
sigCache *txscript.SigCache
|
||||
hashCache *txscript.HashCache
|
||||
}
|
||||
|
||||
// NewBlkTmplGenerator returns a new block template generator for the given
|
||||
|
@ -358,7 +365,8 @@ type BlkTmplGenerator struct {
|
|||
func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params,
|
||||
txSource TxSource, chain *blockchain.BlockChain,
|
||||
timeSource blockchain.MedianTimeSource,
|
||||
sigCache *txscript.SigCache) *BlkTmplGenerator {
|
||||
sigCache *txscript.SigCache,
|
||||
hashCache *txscript.HashCache) *BlkTmplGenerator {
|
||||
|
||||
return &BlkTmplGenerator{
|
||||
policy: policy,
|
||||
|
@ -367,6 +375,7 @@ func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params,
|
|||
chain: chain,
|
||||
timeSource: timeSource,
|
||||
sigCache: sigCache,
|
||||
hashCache: hashCache,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,12 +460,13 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*Bloc
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO(roasbeef): add witnesss commitment output
|
||||
coinbaseTx, err := createCoinbaseTx(g.chainParams, coinbaseScript,
|
||||
nextBlockHeight, payToAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
numCoinbaseSigOps := int64(blockchain.CountSigOps(coinbaseTx))
|
||||
coinbaseSigOpCost := int64(blockchain.CountSigOps(coinbaseTx)) * blockchain.WitnessScaleFactor
|
||||
|
||||
// Get the current source transactions and create a priority queue to
|
||||
// hold the transactions which are ready for inclusion into a block
|
||||
|
@ -490,9 +500,9 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*Bloc
|
|||
// However, since the total fees aren't known yet, use a dummy value for
|
||||
// the coinbase fee which will be updated later.
|
||||
txFees := make([]int64, 0, len(sourceTxns))
|
||||
txSigOpCounts := make([]int64, 0, len(sourceTxns))
|
||||
txSigOpCosts := make([]int64, 0, len(sourceTxns))
|
||||
txFees = append(txFees, -1) // Updated once known
|
||||
txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps)
|
||||
txSigOpCosts = append(txSigOpCosts, coinbaseSigOpCost)
|
||||
|
||||
log.Debugf("Considering %d transactions for inclusion to new block",
|
||||
len(sourceTxns))
|
||||
|
@ -570,6 +580,7 @@ mempoolLoop:
|
|||
nextBlockHeight)
|
||||
|
||||
// Calculate the fee in Satoshi/kB.
|
||||
// TODO(roasbeef): cost accounting by weight
|
||||
prioItem.feePerKB = txDesc.FeePerKB
|
||||
prioItem.fee = txDesc.Fee
|
||||
|
||||
|
@ -591,10 +602,14 @@ mempoolLoop:
|
|||
// The starting block size is the size of the block header plus the max
|
||||
// possible transaction count size, plus the size of the coinbase
|
||||
// transaction.
|
||||
blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())
|
||||
blockSigOps := numCoinbaseSigOps
|
||||
blockWeight := uint32((blockHeaderOverhead * (blockchain.WitnessScaleFactor - 1)) + blockchain.GetTransactionWeight(coinbaseTx))
|
||||
blockSigOpCost := coinbaseSigOpCost
|
||||
totalFees := int64(0)
|
||||
|
||||
// TODO(roasbeef): should be guarded by version bits state check
|
||||
var witnessIncluded bool
|
||||
includeWitness := true
|
||||
|
||||
// Choose which transactions make it into the block.
|
||||
for priorityQueue.Len() > 0 {
|
||||
// Grab the highest priority (or highest fee per kilobyte
|
||||
|
@ -602,45 +617,73 @@ mempoolLoop:
|
|||
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
|
||||
tx := prioItem.tx
|
||||
|
||||
switch {
|
||||
// If segregated witness has not been activated yet, then we
|
||||
// shouldn't include any witness transactions in the block.
|
||||
case tx.HasWitness() && !segwitActive:
|
||||
continue
|
||||
|
||||
// Otherwise, Keep track of if we've included a transaction
|
||||
// with witness data or not. If so, then we'll need to include
|
||||
// the witness commitment as the last output in the coinbase
|
||||
// transaction.
|
||||
case tx.HasWitness() && segwitActive:
|
||||
// If we're about to include a transaction bearing
|
||||
// witness data, then we'll also need to include a
|
||||
// witness commitment in the coinbase transaction.
|
||||
// Therefore, we account for the additional weight
|
||||
// within the block.
|
||||
if !witnessIncluded {
|
||||
// First we account for the additional witness
|
||||
// data in the witness nonce of the coinbaes
|
||||
// transaction: 32-bytes of zeroes.
|
||||
blockWeight += 2 + 32
|
||||
|
||||
// Next we account for the additional flag and
|
||||
// marker bytes in the transaction
|
||||
// serialization.
|
||||
blockWeight += (1 + 1) * blockchain.WitnessScaleFactor
|
||||
|
||||
// Finally we account for the weight of the
|
||||
// additional OP_RETURN output: 8-bytes (value)
|
||||
// + 1-byte (var-int) + 38-bytes (pkScript),
|
||||
// scaling up the weight as it's non-witness
|
||||
// data.
|
||||
blockWeight += (8 + 1 + 38) * blockchain.WitnessScaleFactor
|
||||
}
|
||||
|
||||
witnessIncluded = true
|
||||
}
|
||||
|
||||
// Grab any transactions which depend on this one.
|
||||
deps := dependers[*tx.Hash()]
|
||||
|
||||
// Enforce maximum block size. Also check for overflow.
|
||||
txSize := uint32(tx.MsgTx().SerializeSize())
|
||||
blockPlusTxSize := blockSize + txSize
|
||||
if blockPlusTxSize < blockSize ||
|
||||
blockPlusTxSize >= g.policy.BlockMaxSize {
|
||||
txWeight := uint32(blockchain.GetTransactionWeight(tx))
|
||||
blockPlusTxWeight := uint32(blockWeight + txWeight)
|
||||
if blockPlusTxWeight < blockWeight ||
|
||||
blockPlusTxWeight >= g.policy.BlockMaxWeight {
|
||||
|
||||
log.Tracef("Skipping tx %s because it would exceed "+
|
||||
"the max block size", tx.Hash())
|
||||
"the max block weight", tx.Hash())
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
|
||||
// Enforce maximum signature operations per block. Also check
|
||||
// for overflow.
|
||||
numSigOps := int64(blockchain.CountSigOps(tx))
|
||||
if blockSigOps+numSigOps < blockSigOps ||
|
||||
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
||||
log.Tracef("Skipping tx %s because it would exceed "+
|
||||
"the maximum sigops per block", tx.Hash())
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
numP2SHSigOps, err := blockchain.CountP2SHSigOps(tx, false,
|
||||
blockUtxos)
|
||||
// Enforce maximum signature operation cost per block. Also
|
||||
// check for overflow.
|
||||
sigOpCost, err := blockchain.GetSigOpCost(tx, false,
|
||||
blockUtxos, true, includeWitness)
|
||||
if err != nil {
|
||||
log.Tracef("Skipping tx %s due to error in "+
|
||||
"CountP2SHSigOps: %v", tx.Hash(), err)
|
||||
"GetSigOpCost: %v", tx.Hash(), err)
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
numSigOps += int64(numP2SHSigOps)
|
||||
if blockSigOps+numSigOps < blockSigOps ||
|
||||
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
||||
log.Tracef("Skipping tx %s because it would exceed "+
|
||||
"the maximum sigops per block (p2sh)",
|
||||
tx.Hash())
|
||||
if blockSigOpCost+int64(sigOpCost) < blockSigOpCost ||
|
||||
blockSigOpCost+int64(sigOpCost) > blockchain.MaxBlockSigOpsCost {
|
||||
log.Tracef("Skipping tx %s because it would "+
|
||||
"exceed the maximum sigops per block", tx.Hash())
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
|
@ -649,13 +692,13 @@ mempoolLoop:
|
|||
// minimum block size.
|
||||
if sortedByFee &&
|
||||
prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&
|
||||
blockPlusTxSize >= g.policy.BlockMinSize {
|
||||
blockPlusTxWeight >= g.policy.BlockMinWeight {
|
||||
|
||||
log.Tracef("Skipping tx %s with feePerKB %.2f "+
|
||||
"< TxMinFreeFee %d and block size %d >= "+
|
||||
"minBlockSize %d", tx.Hash(), prioItem.feePerKB,
|
||||
g.policy.TxMinFreeFee, blockPlusTxSize,
|
||||
g.policy.BlockMinSize)
|
||||
log.Tracef("Skipping tx %s with feePerKB %d "+
|
||||
"< TxMinFreeFee %d and block weight %d >= "+
|
||||
"minBlockWeight %d", tx.Hash(), prioItem.feePerKB,
|
||||
g.policy.TxMinFreeFee, blockPlusTxWeight,
|
||||
g.policy.BlockMinWeight)
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
|
@ -663,13 +706,13 @@ mempoolLoop:
|
|||
// Prioritize by fee per kilobyte once the block is larger than
|
||||
// the priority size or there are no more high-priority
|
||||
// transactions.
|
||||
if !sortedByFee && (blockPlusTxSize >= g.policy.BlockPrioritySize ||
|
||||
if !sortedByFee && (blockPlusTxWeight >= g.policy.BlockPrioritySize ||
|
||||
prioItem.priority <= MinHighPriority) {
|
||||
|
||||
log.Tracef("Switching to sort by fees per kilobyte "+
|
||||
"blockSize %d >= BlockPrioritySize %d || "+
|
||||
"priority %.2f <= minHighPriority %.2f",
|
||||
blockPlusTxSize, g.policy.BlockPrioritySize,
|
||||
log.Tracef("Switching to sort by fees per "+
|
||||
"kilobyte blockSize %d >= BlockPrioritySize "+
|
||||
"%d || priority %.2f <= minHighPriority %.2f",
|
||||
blockPlusTxWeight, g.policy.BlockPrioritySize,
|
||||
prioItem.priority, MinHighPriority)
|
||||
|
||||
sortedByFee = true
|
||||
|
@ -677,11 +720,11 @@ mempoolLoop:
|
|||
|
||||
// Put the transaction back into the priority queue and
|
||||
// skip it so it is re-priortized by fees if it won't
|
||||
// fit into the high-priority section or the priority is
|
||||
// too low. Otherwise this transaction will be the
|
||||
// fit into the high-priority section or the priority
|
||||
// is too low. Otherwise this transaction will be the
|
||||
// final one in the high-priority section, so just fall
|
||||
// though to the code below so it is added now.
|
||||
if blockPlusTxSize > g.policy.BlockPrioritySize ||
|
||||
if blockPlusTxWeight > g.policy.BlockPrioritySize ||
|
||||
prioItem.priority < MinHighPriority {
|
||||
|
||||
heap.Push(priorityQueue, prioItem)
|
||||
|
@ -700,11 +743,11 @@ mempoolLoop:
|
|||
continue
|
||||
}
|
||||
err = blockchain.ValidateTransactionScripts(tx, blockUtxos,
|
||||
txscript.StandardVerifyFlags, g.sigCache)
|
||||
txscript.StandardVerifyFlags, g.sigCache,
|
||||
g.hashCache)
|
||||
if err != nil {
|
||||
log.Tracef("Skipping tx %s due to error in "+
|
||||
"ValidateTransactionScripts: %v", tx.Hash(),
|
||||
err)
|
||||
"ValidateTransactionScripts: %v", tx.Hash(), err)
|
||||
logSkippedDeps(tx, deps)
|
||||
continue
|
||||
}
|
||||
|
@ -719,11 +762,11 @@ mempoolLoop:
|
|||
// save the fees and signature operation counts to the block
|
||||
// template.
|
||||
blockTxns = append(blockTxns, tx)
|
||||
blockSize += txSize
|
||||
blockSigOps += numSigOps
|
||||
blockWeight += txWeight
|
||||
blockSigOpCost += int64(sigOpCost)
|
||||
totalFees += prioItem.fee
|
||||
txFees = append(txFees, prioItem.fee)
|
||||
txSigOpCounts = append(txSigOpCounts, numSigOps)
|
||||
txSigOpCosts = append(txSigOpCosts, int64(sigOpCost))
|
||||
|
||||
log.Tracef("Adding tx %s (priority %.2f, feePerKB %.2f)",
|
||||
prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)
|
||||
|
@ -742,13 +785,18 @@ mempoolLoop:
|
|||
}
|
||||
|
||||
// Now that the actual transactions have been selected, update the
|
||||
// block size for the real transaction count and coinbase value with
|
||||
// block weight for the real transaction count and coinbase value with
|
||||
// the total fees accordingly.
|
||||
blockSize -= wire.MaxVarIntPayload -
|
||||
uint32(wire.VarIntSerializeSize(uint64(len(blockTxns))))
|
||||
blockWeight -= wire.MaxVarIntPayload -
|
||||
(uint32(wire.VarIntSerializeSize(uint64(len(blockTxns)))) *
|
||||
(blockchain.WitnessScaleFactor - 1))
|
||||
coinbaseTx.MsgTx().TxOut[0].Value += totalFees
|
||||
txFees[0] = -totalFees
|
||||
|
||||
// TODO(roasbeef): add witness commitment
|
||||
if witnessIncluded {
|
||||
}
|
||||
|
||||
// Calculate the required difficulty for the block. The timestamp
|
||||
// is potentially adjusted to ensure it comes after the median time of
|
||||
// the last several blocks per the chain consensus rules.
|
||||
|
@ -766,7 +814,7 @@ mempoolLoop:
|
|||
}
|
||||
|
||||
// Create a new block ready to be solved.
|
||||
merkles := blockchain.BuildMerkleTreeStore(blockTxns)
|
||||
merkles := blockchain.BuildMerkleTreeStore(blockTxns, false)
|
||||
var msgBlock wire.MsgBlock
|
||||
msgBlock.Header = wire.BlockHeader{
|
||||
Version: nextBlockVersion,
|
||||
|
@ -790,15 +838,15 @@ mempoolLoop:
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("Created new block template (%d transactions, %d in fees, "+
|
||||
"%d signature operations, %d bytes, target difficulty %064x)",
|
||||
len(msgBlock.Transactions), totalFees, blockSigOps, blockSize,
|
||||
blockchain.CompactToBig(msgBlock.Header.Bits))
|
||||
log.Debugf("Created new block template (%d transactions, %d in "+
|
||||
"fees, %d signature operations cost, %d weight, target difficulty "+
|
||||
"%064x)", len(msgBlock.Transactions), totalFees, blockSigOpCost,
|
||||
blockWeight, blockchain.CompactToBig(msgBlock.Header.Bits))
|
||||
|
||||
return &BlockTemplate{
|
||||
Block: &msgBlock,
|
||||
Fees: txFees,
|
||||
SigOpCounts: txSigOpCounts,
|
||||
SigOpCosts: txSigOpCosts,
|
||||
Height: nextBlockHeight,
|
||||
ValidPayAddress: payToAddress != nil,
|
||||
}, nil
|
||||
|
@ -852,7 +900,7 @@ func (g *BlkTmplGenerator) UpdateExtraNonce(msgBlock *wire.MsgBlock, blockHeight
|
|||
|
||||
// Recalculate the merkle root with the updated extra nonce.
|
||||
block := btcutil.NewBlock(msgBlock)
|
||||
merkles := blockchain.BuildMerkleTreeStore(block.Transactions())
|
||||
merkles := blockchain.BuildMerkleTreeStore(block.Transactions(), false)
|
||||
msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -21,12 +21,20 @@ const (
|
|||
// the generation of block templates. See the documentation for
|
||||
// NewBlockTemplate for more details on each of these parameters are used.
|
||||
type Policy struct {
|
||||
// BlockMinSize is the minimum block size in bytes to be used when
|
||||
// BlockMinWeight is the minimum block weight to be used when
|
||||
// generating a block template.
|
||||
BlockMinWeight uint32
|
||||
|
||||
// BlockMaxWeight is the maximum block weight to be used when
|
||||
// generating a block template.
|
||||
BlockMaxWeight uint32
|
||||
|
||||
// BlockMinWeight is the minimum block size to be used when generating
|
||||
// a block template.
|
||||
BlockMinSize uint32
|
||||
|
||||
// BlockMaxSize is the maximum block size in bytes to be used when
|
||||
// generating a block template.
|
||||
// BlockMaxSize is the maximum block size to be used when generating a
|
||||
// block template.
|
||||
BlockMaxSize uint32
|
||||
|
||||
// BlockPrioritySize is the size in bytes for high-priority / low-fee
|
||||
|
|
|
@ -173,6 +173,7 @@ type server struct {
|
|||
addrManager *addrmgr.AddrManager
|
||||
connManager *connmgr.ConnManager
|
||||
sigCache *txscript.SigCache
|
||||
hashCache *txscript.HashCache
|
||||
rpcServer *rpcServer
|
||||
blockManager *blockManager
|
||||
txMemPool *mempool.TxPool
|
||||
|
@ -2412,6 +2413,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
|||
timeSource: blockchain.NewMedianTime(),
|
||||
services: services,
|
||||
sigCache: txscript.NewSigCache(cfg.SigCacheMaxSize),
|
||||
hashCache: txscript.NewHashCache(cfg.SigCacheMaxSize),
|
||||
}
|
||||
|
||||
// Create the transaction and address indexes if needed.
|
||||
|
@ -2459,7 +2461,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
|||
FreeTxRelayLimit: cfg.FreeTxRelayLimit,
|
||||
MaxOrphanTxs: cfg.MaxOrphanTxs,
|
||||
MaxOrphanTxSize: defaultMaxOrphanTxSize,
|
||||
MaxSigOpsPerTx: blockchain.MaxSigOpsPerBlock / 5,
|
||||
MaxSigOpCostPerTx: blockchain.MaxBlockSigOpsCost / 4,
|
||||
MinRelayTxFee: cfg.minRelayTxFee,
|
||||
MaxTxVersion: 2,
|
||||
},
|
||||
|
@ -2483,6 +2485,8 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
|||
// NOTE: The CPU miner relies on the mempool, so the mempool has to be
|
||||
// created before calling the function to create the CPU miner.
|
||||
policy := mining.Policy{
|
||||
BlockMinWeight: cfg.BlockMinWeight,
|
||||
BlockMaxWeight: cfg.BlockMaxWeight,
|
||||
BlockMinSize: cfg.BlockMinSize,
|
||||
BlockMaxSize: cfg.BlockMaxSize,
|
||||
BlockPrioritySize: cfg.BlockPrioritySize,
|
||||
|
@ -2490,7 +2494,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
|||
}
|
||||
blockTemplateGenerator := mining.NewBlkTmplGenerator(&policy,
|
||||
s.chainParams, s.txMemPool, s.blockManager.chain, s.timeSource,
|
||||
s.sigCache)
|
||||
s.sigCache, s.hashCache)
|
||||
s.cpuMiner = cpuminer.New(&cpuminer.Config{
|
||||
ChainParams: chainParams,
|
||||
BlockTemplateGenerator: blockTemplateGenerator,
|
||||
|
|
Loading…
Reference in a new issue