Skip to content

Commit

Permalink
multi: replace usage of BuildMerkleTreeStore with CalcMerkleRoot
Browse files Browse the repository at this point in the history
  • Loading branch information
cfromknecht authored and kcalvinalvin committed May 9, 2023
1 parent c1dc927 commit fd2f936
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 38 deletions.
3 changes: 1 addition & 2 deletions blockchain/fullblocktests/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,7 @@ func calcMerkleRoot(txns []*wire.MsgTx) chainhash.Hash {
for _, tx := range txns {
utilTxns = append(utilTxns, btcutil.NewTx(tx))
}
merkles := blockchain.BuildMerkleTreeStore(utilTxns, false)
return *merkles[len(merkles)-1]
return blockchain.CalcMerkleRoot(utilTxns, false)
}

// solveBlock attempts to find a nonce which makes the passed block header hash
Expand Down
3 changes: 1 addition & 2 deletions blockchain/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,7 @@ func ValidateWitnessCommitment(blk *btcutil.Block) error {
// the extracted witnessCommitment is equal to:
// SHA256(witnessMerkleRoot || witnessNonce). Where witnessNonce is the
// coinbase transaction's only witness item.
witnessMerkleTree := BuildMerkleTreeStore(blk.Transactions(), true)
witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1]
witnessMerkleRoot := CalcMerkleRoot(blk.Transactions(), true)

var witnessPreimage [chainhash.HashSize * 2]byte
copy(witnessPreimage[:], witnessMerkleRoot[:])
Expand Down
7 changes: 3 additions & 4 deletions blockchain/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,11 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median
// checks. Bitcoind builds the tree here and checks the merkle root
// after the following checks, but there is no reason not to check the
// merkle root matches here.
merkles := BuildMerkleTreeStore(block.Transactions(), false)
calculatedMerkleRoot := merkles[len(merkles)-1]
if !header.MerkleRoot.IsEqual(calculatedMerkleRoot) {
calcMerkleRoot := CalcMerkleRoot(block.Transactions(), false)
if !header.MerkleRoot.IsEqual(&calcMerkleRoot) {
str := fmt.Sprintf("block merkle root is invalid - block "+
"header indicates %v, but calculated value is %v",
header.MerkleRoot, calculatedMerkleRoot)
header.MerkleRoot, calcMerkleRoot)
return ruleError(ErrBadMerkleRoot, str)
}

Expand Down
6 changes: 3 additions & 3 deletions integration/rpctest/blockgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import (
"time"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/mining"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/btcutil"
)

// solveBlock attempts to find a nonce which makes the passed block header hash
Expand Down Expand Up @@ -197,12 +197,12 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx,
_ = mining.AddWitnessCommitment(coinbaseTx, blockTxns)
}

merkles := blockchain.BuildMerkleTreeStore(blockTxns, false)
merkleRoot := blockchain.CalcMerkleRoot(blockTxns, false)
var block wire.MsgBlock
block.Header = wire.BlockHeader{
Version: blockVersion,
PrevBlock: *prevHash,
MerkleRoot: *merkles[len(merkles)-1],
MerkleRoot: merkleRoot,
Timestamp: ts,
Bits: net.PowLimitBits,
}
Expand Down
81 changes: 56 additions & 25 deletions mining/mining.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
"time"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/btcutil"
)

const (
Expand Down Expand Up @@ -420,26 +420,26 @@ func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params,
//
// Given the above, a block generated by this function is of the following form:
//
// ----------------------------------- -- --
// | Coinbase Transaction | | |
// |-----------------------------------| | |
// | | | | ----- policy.BlockPrioritySize
// | High-priority Transactions | | |
// | | | |
// |-----------------------------------| | --
// | | |
// | | |
// | | |--- policy.BlockMaxSize
// | Transactions prioritized by fee | |
// | until <= policy.TxMinFreeFee | |
// | | |
// | | |
// | | |
// |-----------------------------------| |
// | Low-fee/Non high-priority (free) | |
// | transactions (while block size | |
// | <= policy.BlockMinSize) | |
// ----------------------------------- --
// ----------------------------------- -- --
// | Coinbase Transaction | | |
// |-----------------------------------| | |
// | | | | ----- policy.BlockPrioritySize
// | High-priority Transactions | | |
// | | | |
// |-----------------------------------| | --
// | | |
// | | |
// | | |--- policy.BlockMaxSize
// | Transactions prioritized by fee | |
// | until <= policy.TxMinFreeFee | |
// | | |
// | | |
// | | |
// |-----------------------------------| |
// | Low-fee/Non high-priority (free) | |
// | transactions (while block size | |
// | <= policy.BlockMinSize) | |
// ----------------------------------- --
func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) {
// Extend the most recently known best block.
best := g.chain.BestSnapshot()
Expand Down Expand Up @@ -804,6 +804,38 @@ mempoolLoop:
var witnessCommitment []byte
if witnessIncluded {
witnessCommitment = AddWitnessCommitment(coinbaseTx, blockTxns)
// 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.
witnessMerkleRoot := blockchain.CalcMerkleRoot(blockTxns, true)

// 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
Expand All @@ -823,12 +855,11 @@ mempoolLoop:
}

// Create a new block ready to be solved.
merkles := blockchain.BuildMerkleTreeStore(blockTxns, false)
var msgBlock wire.MsgBlock
msgBlock.Header = wire.BlockHeader{
Version: nextBlockVersion,
PrevBlock: best.Hash,
MerkleRoot: *merkles[len(merkles)-1],
MerkleRoot: blockchain.CalcMerkleRoot(blockTxns, false),
Timestamp: ts,
Bits: reqDifficulty,
}
Expand Down Expand Up @@ -953,8 +984,8 @@ 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(), false)
msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
merkleRoot := blockchain.CalcMerkleRoot(block.Transactions(), false)
msgBlock.Header.MerkleRoot = merkleRoot
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1651,8 +1651,8 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo

// Update the merkle root.
block := btcutil.NewBlock(template.Block)
merkles := blockchain.BuildMerkleTreeStore(block.Transactions(), false)
template.Block.Header.MerkleRoot = *merkles[len(merkles)-1]
merkleRoot := blockchain.CalcMerkleRoot(block.Transactions(), false)
template.Block.Header.MerkleRoot = merkleRoot
}

// Set locals for convenience.
Expand Down

0 comments on commit fd2f936

Please sign in to comment.