mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-10-14 00:59: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 (
|
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
|
// MaxTimeOffsetSeconds is the maximum number of seconds a block time
|
||||||
// is allowed to be ahead of the current time. This is currently 2
|
// is allowed to be ahead of the current time. This is currently 2
|
||||||
// hours.
|
// hours.
|
||||||
|
193
mining/mining.go
193
mining/mining.go
@ -5,7 +5,6 @@
|
|||||||
package mining
|
package mining
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
@ -198,9 +197,9 @@ type BlockTemplate struct {
|
|||||||
// sum of the fees of all other transactions.
|
// sum of the fees of all other transactions.
|
||||||
Fees []int64
|
Fees []int64
|
||||||
|
|
||||||
// SigOpCosts contains the number of signature operations each
|
// SigOpCounts contains the number of signature operations each
|
||||||
// transaction in the generated template performs.
|
// transaction in the generated template performs.
|
||||||
SigOpCosts []int64
|
SigOpCounts []int64
|
||||||
|
|
||||||
// Height is the height at which the block template connects to the main
|
// Height is the height at which the block template connects to the main
|
||||||
// chain.
|
// chain.
|
||||||
@ -211,12 +210,6 @@ type BlockTemplate struct {
|
|||||||
// NewBlockTemplate for details on which this can be useful to generate
|
// NewBlockTemplate for details on which this can be useful to generate
|
||||||
// templates without a coinbase payment address.
|
// templates without a coinbase payment address.
|
||||||
ValidPayAddress bool
|
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
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// Get the current source transactions and create a priority queue to
|
||||||
// hold the transactions which are ready for inclusion into a block
|
// 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
|
// However, since the total fees aren't known yet, use a dummy value for
|
||||||
// the coinbase fee which will be updated later.
|
// the coinbase fee which will be updated later.
|
||||||
txFees := make([]int64, 0, len(sourceTxns))
|
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
|
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",
|
log.Debugf("Considering %d transactions for inclusion to new block",
|
||||||
len(sourceTxns))
|
len(sourceTxns))
|
||||||
@ -597,23 +590,10 @@ mempoolLoop:
|
|||||||
// The starting block size is the size of the block header plus the max
|
// The starting block size is the size of the block header plus the max
|
||||||
// possible transaction count size, plus the size of the coinbase
|
// possible transaction count size, plus the size of the coinbase
|
||||||
// transaction.
|
// transaction.
|
||||||
blockWeight := uint32((blockHeaderOverhead * blockchain.WitnessScaleFactor) +
|
blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())
|
||||||
blockchain.GetTransactionWeight(coinbaseTx))
|
blockSigOps := numCoinbaseSigOps
|
||||||
blockSigOpCost := coinbaseSigOpCost
|
|
||||||
totalFees := int64(0)
|
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.
|
// Choose which transactions make it into the block.
|
||||||
for priorityQueue.Len() > 0 {
|
for priorityQueue.Len() > 0 {
|
||||||
// Grab the highest priority (or highest fee per kilobyte
|
// Grab the highest priority (or highest fee per kilobyte
|
||||||
@ -621,72 +601,42 @@ mempoolLoop:
|
|||||||
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
|
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
|
||||||
tx := prioItem.tx
|
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.
|
// Grab any transactions which depend on this one.
|
||||||
deps := dependers[*tx.Hash()]
|
deps := dependers[*tx.Hash()]
|
||||||
|
|
||||||
// Enforce maximum block size. Also check for overflow.
|
// Enforce maximum block size. Also check for overflow.
|
||||||
txWeight := uint32(blockchain.GetTransactionWeight(tx))
|
txSize := uint32(tx.MsgTx().SerializeSize())
|
||||||
blockPlusTxWeight := blockWeight + txWeight
|
blockPlusTxSize := blockSize + txSize
|
||||||
if blockPlusTxWeight < blockWeight ||
|
if blockPlusTxSize < blockSize ||
|
||||||
blockPlusTxWeight >= g.policy.BlockMaxWeight {
|
blockPlusTxSize >= g.policy.BlockMaxSize {
|
||||||
|
|
||||||
log.Tracef("Skipping tx %s because it would exceed "+
|
log.Tracef("Skipping tx %s because it would exceed "+
|
||||||
"the max block weight", tx.Hash())
|
"the max block size", tx.Hash())
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce maximum signature operation cost per block. Also
|
// Enforce maximum signature operations per block. Also check
|
||||||
// check for overflow.
|
// for overflow.
|
||||||
sigOpCost, err := blockchain.GetSigOpCost(tx, false,
|
numSigOps := int64(blockchain.CountSigOps(tx))
|
||||||
blockUtxos, true, segwitActive)
|
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 {
|
if err != nil {
|
||||||
log.Tracef("Skipping tx %s due to error in "+
|
log.Tracef("Skipping tx %s due to error in "+
|
||||||
"GetSigOpCost: %v", tx.Hash(), err)
|
"GetSigOpCost: %v", tx.Hash(), err)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if blockSigOpCost+int64(sigOpCost) < blockSigOpCost ||
|
numSigOps += int64(numP2SHSigOps)
|
||||||
blockSigOpCost+int64(sigOpCost) > blockchain.MaxBlockSigOpsCost {
|
if blockSigOps+numSigOps < blockSigOps ||
|
||||||
|
blockSigOps+numSigOps > blockchain.MaxBlockSigOpsCost {
|
||||||
log.Tracef("Skipping tx %s because it would "+
|
log.Tracef("Skipping tx %s because it would "+
|
||||||
"exceed the maximum sigops per block", tx.Hash())
|
"exceed the maximum sigops per block", tx.Hash())
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
@ -697,13 +647,13 @@ mempoolLoop:
|
|||||||
// minimum block size.
|
// minimum block size.
|
||||||
if sortedByFee &&
|
if sortedByFee &&
|
||||||
prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&
|
prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&
|
||||||
blockPlusTxWeight >= g.policy.BlockMinWeight {
|
blockPlusTxSize >= g.policy.BlockMinSize {
|
||||||
|
|
||||||
log.Tracef("Skipping tx %s with feePerKB %d "+
|
log.Tracef("Skipping tx %s with feePerKB %.2f "+
|
||||||
"< TxMinFreeFee %d and block weight %d >= "+
|
"< TxMinFreeFee %d and block size %d >= "+
|
||||||
"minBlockWeight %d", tx.Hash(), prioItem.feePerKB,
|
"minBlockSize %d", tx.Hash(), prioItem.feePerKB,
|
||||||
g.policy.TxMinFreeFee, blockPlusTxWeight,
|
g.policy.TxMinFreeFee, blockPlusTxSize,
|
||||||
g.policy.BlockMinWeight)
|
g.policy.BlockMinSize)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -711,13 +661,13 @@ mempoolLoop:
|
|||||||
// Prioritize by fee per kilobyte once the block is larger than
|
// Prioritize by fee per kilobyte once the block is larger than
|
||||||
// the priority size or there are no more high-priority
|
// the priority size or there are no more high-priority
|
||||||
// transactions.
|
// transactions.
|
||||||
if !sortedByFee && (blockPlusTxWeight >= g.policy.BlockPrioritySize ||
|
if !sortedByFee && (blockPlusTxSize >= g.policy.BlockPrioritySize ||
|
||||||
prioItem.priority <= MinHighPriority) {
|
prioItem.priority <= MinHighPriority) {
|
||||||
|
|
||||||
log.Tracef("Switching to sort by fees per "+
|
log.Tracef("Switching to sort by fees per kilobyte "+
|
||||||
"kilobyte blockSize %d >= BlockPrioritySize "+
|
"blockSize %d >= BlockPrioritySize %d || "+
|
||||||
"%d || priority %.2f <= minHighPriority %.2f",
|
"priority %.2f <= minHighPriority %.2f",
|
||||||
blockPlusTxWeight, g.policy.BlockPrioritySize,
|
blockPlusTxSize, g.policy.BlockPrioritySize,
|
||||||
prioItem.priority, MinHighPriority)
|
prioItem.priority, MinHighPriority)
|
||||||
|
|
||||||
sortedByFee = true
|
sortedByFee = true
|
||||||
@ -729,7 +679,7 @@ mempoolLoop:
|
|||||||
// is too low. Otherwise this transaction will be the
|
// is too low. Otherwise this transaction will be the
|
||||||
// final one in the high-priority section, so just fall
|
// final one in the high-priority section, so just fall
|
||||||
// though to the code below so it is added now.
|
// though to the code below so it is added now.
|
||||||
if blockPlusTxWeight > g.policy.BlockPrioritySize ||
|
if blockPlusTxSize > g.policy.BlockPrioritySize ||
|
||||||
prioItem.priority < MinHighPriority {
|
prioItem.priority < MinHighPriority {
|
||||||
|
|
||||||
heap.Push(priorityQueue, prioItem)
|
heap.Push(priorityQueue, prioItem)
|
||||||
@ -767,11 +717,11 @@ mempoolLoop:
|
|||||||
// save the fees and signature operation counts to the block
|
// save the fees and signature operation counts to the block
|
||||||
// template.
|
// template.
|
||||||
blockTxns = append(blockTxns, tx)
|
blockTxns = append(blockTxns, tx)
|
||||||
blockWeight += txWeight
|
blockSize += txSize
|
||||||
blockSigOpCost += int64(sigOpCost)
|
blockSigOps += int64(numSigOps)
|
||||||
totalFees += prioItem.fee
|
totalFees += prioItem.fee
|
||||||
txFees = append(txFees, 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)",
|
log.Tracef("Adding tx %s (priority %.2f, feePerKB %.2f)",
|
||||||
prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)
|
prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)
|
||||||
@ -790,55 +740,13 @@ mempoolLoop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now that the actual transactions have been selected, update the
|
// 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.
|
// the total fees accordingly.
|
||||||
blockWeight -= wire.MaxVarIntPayload -
|
blockSize -= wire.MaxVarIntPayload -
|
||||||
(uint32(wire.VarIntSerializeSize(uint64(len(blockTxns)))) *
|
uint32(wire.VarIntSerializeSize(uint64(len(blockTxns))))
|
||||||
blockchain.WitnessScaleFactor)
|
|
||||||
coinbaseTx.MsgTx().TxOut[0].Value += totalFees
|
coinbaseTx.MsgTx().TxOut[0].Value += totalFees
|
||||||
txFees[0] = -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
|
// Calculate the required difficulty for the block. The timestamp
|
||||||
// is potentially adjusted to ensure it comes after the median time of
|
// is potentially adjusted to ensure it comes after the median time of
|
||||||
// the last several blocks per the chain consensus rules.
|
// the last several blocks per the chain consensus rules.
|
||||||
@ -880,18 +788,17 @@ mempoolLoop:
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Created new block template (%d transactions, %d in "+
|
log.Debugf("Created new block template (%d transactions, %d in fees, "+
|
||||||
"fees, %d signature operations cost, %d weight, target difficulty "+
|
"%d signature operations, %d bytes, target difficulty %064x)",
|
||||||
"%064x)", len(msgBlock.Transactions), totalFees, blockSigOpCost,
|
len(msgBlock.Transactions), totalFees, blockSigOps, blockSize,
|
||||||
blockWeight, blockchain.CompactToBig(msgBlock.Header.Bits))
|
blockchain.CompactToBig(msgBlock.Header.Bits))
|
||||||
|
|
||||||
return &BlockTemplate{
|
return &BlockTemplate{
|
||||||
Block: &msgBlock,
|
Block: &msgBlock,
|
||||||
Fees: txFees,
|
Fees: txFees,
|
||||||
SigOpCosts: txSigOpCosts,
|
SigOpCounts: txSigOpCounts,
|
||||||
Height: nextBlockHeight,
|
Height: nextBlockHeight,
|
||||||
ValidPayAddress: payToAddress != nil,
|
ValidPayAddress: payToAddress != nil,
|
||||||
WitnessCommitment: witnessCommitment,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,15 +21,7 @@ const (
|
|||||||
// the generation of block templates. See the documentation for
|
// the generation of block templates. See the documentation for
|
||||||
// NewBlockTemplate for more details on each of these parameters are used.
|
// NewBlockTemplate for more details on each of these parameters are used.
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
// BlockMinWeight is the minimum block weight to be used when
|
// BlockMinSize is the minimum block size to be used when generating
|
||||||
// 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.
|
// a block template.
|
||||||
BlockMinSize uint32
|
BlockMinSize uint32
|
||||||
|
|
||||||
|
@ -1695,7 +1695,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
|||||||
Hash: txHash.String(),
|
Hash: txHash.String(),
|
||||||
Depends: depends,
|
Depends: depends,
|
||||||
Fee: template.Fees[i],
|
Fee: template.Fees[i],
|
||||||
SigOps: template.SigOpCosts[i],
|
SigOps: template.SigOpCounts[i],
|
||||||
}
|
}
|
||||||
transactions = append(transactions, resultTx)
|
transactions = append(transactions, resultTx)
|
||||||
}
|
}
|
||||||
@ -1754,7 +1754,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
|||||||
Hash: tx.TxHash().String(),
|
Hash: tx.TxHash().String(),
|
||||||
Depends: []int64{},
|
Depends: []int64{},
|
||||||
Fee: template.Fees[0],
|
Fee: template.Fees[0],
|
||||||
SigOps: template.SigOpCosts[0],
|
SigOps: template.SigOpCounts[0],
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.CoinbaseTxn = &resultTx
|
reply.CoinbaseTxn = &resultTx
|
||||||
|
Loading…
x
Reference in New Issue
Block a user