mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
(#DEV-14) Removed anything concerning segwit from mining package
This commit is contained in:
parent
7930ceebd4
commit
ffdb76ecec
@ -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.
|
||||
|
201
mining/mining.go
201
mining/mining.go
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user