(#DEV-14) Removed anything concerning segwit from mining package

This commit is contained in:
Mike Zak 2018-06-07 18:36:27 +03:00
parent 7930ceebd4
commit ffdb76ecec
4 changed files with 61 additions and 158 deletions

View File

@ -19,6 +19,10 @@ import (
)
const (
// MaxSigOpsPerBlock is the maximum number of signature operations
// allowed for a block. It is a fraction of the max block payload size.
MaxSigOpsPerBlock = wire.MaxBlockPayload / 50
// MaxTimeOffsetSeconds is the maximum number of seconds a block time
// is allowed to be ahead of the current time. This is currently 2
// hours.

View File

@ -5,7 +5,6 @@
package mining
import (
"bytes"
"container/heap"
"fmt"
"time"
@ -198,9 +197,9 @@ type BlockTemplate struct {
// sum of the fees of all other transactions.
Fees []int64
// SigOpCosts contains the number of signature operations each
// SigOpCounts contains the number of signature operations each
// transaction in the generated template performs.
SigOpCosts []int64
SigOpCounts []int64
// Height is the height at which the block template connects to the main
// chain.
@ -211,12 +210,6 @@ 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 viewB to viewA. The result is that
@ -463,7 +456,7 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*Bloc
if err != nil {
return nil, err
}
coinbaseSigOpCost := int64(blockchain.CountSigOps(coinbaseTx)) * blockchain.WitnessScaleFactor
numCoinbaseSigOps := int64(blockchain.CountSigOps(coinbaseTx))
// Get the current source transactions and create a priority queue to
// hold the transactions which are ready for inclusion into a block
@ -497,9 +490,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))
txSigOpCosts := make([]int64, 0, len(sourceTxns))
txSigOpCounts := make([]int64, 0, len(sourceTxns))
txFees = append(txFees, -1) // Updated once known
txSigOpCosts = append(txSigOpCosts, coinbaseSigOpCost)
txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps)
log.Debugf("Considering %d transactions for inclusion to new block",
len(sourceTxns))
@ -597,23 +590,10 @@ 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.
blockWeight := uint32((blockHeaderOverhead * blockchain.WitnessScaleFactor) +
blockchain.GetTransactionWeight(coinbaseTx))
blockSigOpCost := coinbaseSigOpCost
blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())
blockSigOps := numCoinbaseSigOps
totalFees := int64(0)
// Query the version bits state to see if segwit has been activated, if
// so then this means that we'll include any transactions with witness
// data in the mempool, and also add the witness commitment as an
// OP_RETURN output in the coinbase transaction.
segwitState, err := g.chain.ThresholdState(chaincfg.DeploymentSegwit)
if err != nil {
return nil, err
}
segwitActive := segwitState == blockchain.ThresholdActive
witnessIncluded := false
// Choose which transactions make it into the block.
for priorityQueue.Len() > 0 {
// Grab the highest priority (or highest fee per kilobyte
@ -621,72 +601,42 @@ 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 !segwitActive && tx.HasWitness():
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 segwitActive && !witnessIncluded && tx.HasWitness():
// 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 with a model coinbase tx with a
// witness commitment.
coinbaseCopy := btcutil.NewTx(coinbaseTx.MsgTx().Copy())
coinbaseCopy.MsgTx().TxIn[0].Witness = [][]byte{
bytes.Repeat([]byte("a"),
blockchain.CoinbaseWitnessDataLen),
}
coinbaseCopy.MsgTx().AddTxOut(&wire.TxOut{
PkScript: bytes.Repeat([]byte("a"),
blockchain.CoinbaseWitnessPkScriptLength),
})
// In order to accurately account for the weight
// addition due to this coinbase transaction, we'll add
// the difference of the transaction before and after
// the addition of the commitment to the block weight.
weightDiff := blockchain.GetTransactionWeight(coinbaseCopy) -
blockchain.GetTransactionWeight(coinbaseTx)
blockWeight += uint32(weightDiff)
witnessIncluded = true
}
// Grab any transactions which depend on this one.
deps := dependers[*tx.Hash()]
// Enforce maximum block size. Also check for overflow.
txWeight := uint32(blockchain.GetTransactionWeight(tx))
blockPlusTxWeight := blockWeight + txWeight
if blockPlusTxWeight < blockWeight ||
blockPlusTxWeight >= g.policy.BlockMaxWeight {
txSize := uint32(tx.MsgTx().SerializeSize())
blockPlusTxSize := blockSize + txSize
if blockPlusTxSize < blockSize ||
blockPlusTxSize >= g.policy.BlockMaxSize {
log.Tracef("Skipping tx %s because it would exceed "+
"the max block weight", tx.Hash())
"the max block size", tx.Hash())
logSkippedDeps(tx, deps)
continue
}
// Enforce maximum signature operation cost per block. Also
// check for overflow.
sigOpCost, err := blockchain.GetSigOpCost(tx, false,
blockUtxos, true, segwitActive)
// 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)
if err != nil {
log.Tracef("Skipping tx %s due to error in "+
"GetSigOpCost: %v", tx.Hash(), err)
logSkippedDeps(tx, deps)
continue
}
if blockSigOpCost+int64(sigOpCost) < blockSigOpCost ||
blockSigOpCost+int64(sigOpCost) > blockchain.MaxBlockSigOpsCost {
numSigOps += int64(numP2SHSigOps)
if blockSigOps+numSigOps < blockSigOps ||
blockSigOps+numSigOps > blockchain.MaxBlockSigOpsCost {
log.Tracef("Skipping tx %s because it would "+
"exceed the maximum sigops per block", tx.Hash())
logSkippedDeps(tx, deps)
@ -697,13 +647,13 @@ mempoolLoop:
// minimum block size.
if sortedByFee &&
prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&
blockPlusTxWeight >= g.policy.BlockMinWeight {
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)
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)
logSkippedDeps(tx, deps)
continue
}
@ -711,13 +661,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 && (blockPlusTxWeight >= g.policy.BlockPrioritySize ||
if !sortedByFee && (blockPlusTxSize >= g.policy.BlockPrioritySize ||
prioItem.priority <= MinHighPriority) {
log.Tracef("Switching to sort by fees per "+
"kilobyte blockSize %d >= BlockPrioritySize "+
"%d || priority %.2f <= minHighPriority %.2f",
blockPlusTxWeight, g.policy.BlockPrioritySize,
log.Tracef("Switching to sort by fees per kilobyte "+
"blockSize %d >= BlockPrioritySize %d || "+
"priority %.2f <= minHighPriority %.2f",
blockPlusTxSize, g.policy.BlockPrioritySize,
prioItem.priority, MinHighPriority)
sortedByFee = true
@ -729,7 +679,7 @@ mempoolLoop:
// 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 blockPlusTxWeight > g.policy.BlockPrioritySize ||
if blockPlusTxSize > g.policy.BlockPrioritySize ||
prioItem.priority < MinHighPriority {
heap.Push(priorityQueue, prioItem)
@ -767,11 +717,11 @@ mempoolLoop:
// save the fees and signature operation counts to the block
// template.
blockTxns = append(blockTxns, tx)
blockWeight += txWeight
blockSigOpCost += int64(sigOpCost)
blockSize += txSize
blockSigOps += int64(numSigOps)
totalFees += prioItem.fee
txFees = append(txFees, prioItem.fee)
txSigOpCosts = append(txSigOpCosts, int64(sigOpCost))
txSigOpCounts = append(txSigOpCounts, numSigOps)
log.Tracef("Adding tx %s (priority %.2f, feePerKB %.2f)",
prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)
@ -790,55 +740,13 @@ mempoolLoop:
}
// Now that the actual transactions have been selected, update the
// block weight for the real transaction count and coinbase value with
// block size for the real transaction count and coinbase value with
// the total fees accordingly.
blockWeight -= wire.MaxVarIntPayload -
(uint32(wire.VarIntSerializeSize(uint64(len(blockTxns)))) *
blockchain.WitnessScaleFactor)
blockSize -= wire.MaxVarIntPayload -
uint32(wire.VarIntSerializeSize(uint64(len(blockTxns))))
coinbaseTx.MsgTx().TxOut[0].Value += totalFees
txFees[0] = -totalFees
// If segwit is active and we included transactions with witness data,
// then we'll need to include a commitment to the witness data in an
// OP_RETURN output within the coinbase transaction.
var witnessCommitment []byte
if witnessIncluded {
// The witness of the coinbase transaction MUST be exactly 32-bytes
// of all zeroes.
var witnessNonce [blockchain.CoinbaseWitnessDataLen]byte
coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]}
// Next, obtain the merkle root of a tree which consists of the
// wtxid of all transactions in the block. The coinbase
// transaction will have a special wtxid of all zeroes.
witnessMerkleTree := blockchain.BuildMerkleTreeStore(blockTxns,
true)
witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1]
// The preimage to the witness commitment is:
// witnessRoot || coinbaseWitness
var witnessPreimage [64]byte
copy(witnessPreimage[:32], witnessMerkleRoot[:])
copy(witnessPreimage[32:], witnessNonce[:])
// The witness commitment itself is the double-sha256 of the
// witness preimage generated above. With the commitment
// generated, the witness script for the output is: OP_RETURN
// OP_DATA_36 {0xaa21a9ed || witnessCommitment}. The leading
// prefix is referred to as the "witness magic bytes".
witnessCommitment = chainhash.DoubleHashB(witnessPreimage[:])
witnessScript := append(blockchain.WitnessMagicBytes, witnessCommitment...)
// Finally, create the OP_RETURN carrying witness commitment
// output as an additional output within the coinbase.
commitmentOutput := &wire.TxOut{
Value: 0,
PkScript: witnessScript,
}
coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut,
commitmentOutput)
}
// 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.
@ -880,18 +788,17 @@ mempoolLoop:
return nil, err
}
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))
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))
return &BlockTemplate{
Block: &msgBlock,
Fees: txFees,
SigOpCosts: txSigOpCosts,
Height: nextBlockHeight,
ValidPayAddress: payToAddress != nil,
WitnessCommitment: witnessCommitment,
Block: &msgBlock,
Fees: txFees,
SigOpCounts: txSigOpCounts,
Height: nextBlockHeight,
ValidPayAddress: payToAddress != nil,
}, nil
}

View File

@ -21,15 +21,7 @@ const (
// the generation of block templates. See the documentation for
// NewBlockTemplate for more details on each of these parameters are used.
type Policy struct {
// 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
// BlockMinSize is the minimum block size to be used when generating
// a block template.
BlockMinSize uint32

View File

@ -1695,7 +1695,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
Hash: txHash.String(),
Depends: depends,
Fee: template.Fees[i],
SigOps: template.SigOpCosts[i],
SigOps: template.SigOpCounts[i],
}
transactions = append(transactions, resultTx)
}
@ -1754,7 +1754,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
Hash: tx.TxHash().String(),
Depends: []int64{},
Fee: template.Fees[0],
SigOps: template.SigOpCosts[0],
SigOps: template.SigOpCounts[0],
}
reply.CoinbaseTxn = &resultTx