Merge pull request #1716 from halseth/witness-commitment-rpctest
rpctest: add witness commitment when calling CreateBlock
This commit is contained in:
commit
ce697fe7e8
2 changed files with 60 additions and 34 deletions
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/btcsuite/btcd/blockchain"
|
||||
"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/btcutil"
|
||||
|
@ -181,6 +182,21 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx,
|
|||
if inclusionTxs != nil {
|
||||
blockTxns = append(blockTxns, inclusionTxs...)
|
||||
}
|
||||
|
||||
// We must add the witness commitment to the coinbase if any
|
||||
// transactions are segwit.
|
||||
witnessIncluded := false
|
||||
for i := 1; i < len(blockTxns); i++ {
|
||||
if blockTxns[i].MsgTx().HasWitness() {
|
||||
witnessIncluded = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if witnessIncluded {
|
||||
_ = mining.AddWitnessCommitment(coinbaseTx, blockTxns)
|
||||
}
|
||||
|
||||
merkles := blockchain.BuildMerkleTreeStore(blockTxns, false)
|
||||
var block wire.MsgBlock
|
||||
block.Header = wire.BlockHeader{
|
||||
|
|
|
@ -803,40 +803,7 @@ mempoolLoop:
|
|||
// 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)
|
||||
witnessCommitment = AddWitnessCommitment(coinbaseTx, blockTxns)
|
||||
}
|
||||
|
||||
// Calculate the required difficulty for the block. The timestamp
|
||||
|
@ -895,6 +862,49 @@ mempoolLoop:
|
|||
}, nil
|
||||
}
|
||||
|
||||
// AddWitnessCommitment adds the witness commitment as an OP_RETURN outpout
|
||||
// within the coinbase tx. The raw commitment is returned.
|
||||
func AddWitnessCommitment(coinbaseTx *btcutil.Tx,
|
||||
blockTxns []*btcutil.Tx) []byte {
|
||||
|
||||
// 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)
|
||||
|
||||
return witnessCommitment
|
||||
}
|
||||
|
||||
// UpdateBlockTime updates the timestamp in the header of the passed block to
|
||||
// the current time while taking into account the median time of the last
|
||||
// several blocks to ensure the new time is after that time per the chain
|
||||
|
|
Loading…
Reference in a new issue