Skip to content

Commit ce697fe

Browse files
authored
Merge pull request #1716 from halseth/witness-commitment-rpctest
rpctest: add witness commitment when calling CreateBlock
2 parents 7eba688 + 37a6e84 commit ce697fe

2 files changed

Lines changed: 60 additions & 34 deletions

File tree

integration/rpctest/blockgen.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/btcsuite/btcd/blockchain"
1515
"github.com/btcsuite/btcd/chaincfg"
1616
"github.com/btcsuite/btcd/chaincfg/chainhash"
17+
"github.com/btcsuite/btcd/mining"
1718
"github.com/btcsuite/btcd/txscript"
1819
"github.com/btcsuite/btcd/wire"
1920
"github.com/btcsuite/btcutil"
@@ -181,6 +182,21 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx,
181182
if inclusionTxs != nil {
182183
blockTxns = append(blockTxns, inclusionTxs...)
183184
}
185+
186+
// We must add the witness commitment to the coinbase if any
187+
// transactions are segwit.
188+
witnessIncluded := false
189+
for i := 1; i < len(blockTxns); i++ {
190+
if blockTxns[i].MsgTx().HasWitness() {
191+
witnessIncluded = true
192+
break
193+
}
194+
}
195+
196+
if witnessIncluded {
197+
_ = mining.AddWitnessCommitment(coinbaseTx, blockTxns)
198+
}
199+
184200
merkles := blockchain.BuildMerkleTreeStore(blockTxns, false)
185201
var block wire.MsgBlock
186202
block.Header = wire.BlockHeader{

mining/mining.go

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -803,40 +803,7 @@ mempoolLoop:
803803
// OP_RETURN output within the coinbase transaction.
804804
var witnessCommitment []byte
805805
if witnessIncluded {
806-
// The witness of the coinbase transaction MUST be exactly 32-bytes
807-
// of all zeroes.
808-
var witnessNonce [blockchain.CoinbaseWitnessDataLen]byte
809-
coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]}
810-
811-
// Next, obtain the merkle root of a tree which consists of the
812-
// wtxid of all transactions in the block. The coinbase
813-
// transaction will have a special wtxid of all zeroes.
814-
witnessMerkleTree := blockchain.BuildMerkleTreeStore(blockTxns,
815-
true)
816-
witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1]
817-
818-
// The preimage to the witness commitment is:
819-
// witnessRoot || coinbaseWitness
820-
var witnessPreimage [64]byte
821-
copy(witnessPreimage[:32], witnessMerkleRoot[:])
822-
copy(witnessPreimage[32:], witnessNonce[:])
823-
824-
// The witness commitment itself is the double-sha256 of the
825-
// witness preimage generated above. With the commitment
826-
// generated, the witness script for the output is: OP_RETURN
827-
// OP_DATA_36 {0xaa21a9ed || witnessCommitment}. The leading
828-
// prefix is referred to as the "witness magic bytes".
829-
witnessCommitment = chainhash.DoubleHashB(witnessPreimage[:])
830-
witnessScript := append(blockchain.WitnessMagicBytes, witnessCommitment...)
831-
832-
// Finally, create the OP_RETURN carrying witness commitment
833-
// output as an additional output within the coinbase.
834-
commitmentOutput := &wire.TxOut{
835-
Value: 0,
836-
PkScript: witnessScript,
837-
}
838-
coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut,
839-
commitmentOutput)
806+
witnessCommitment = AddWitnessCommitment(coinbaseTx, blockTxns)
840807
}
841808

842809
// Calculate the required difficulty for the block. The timestamp
@@ -895,6 +862,49 @@ mempoolLoop:
895862
}, nil
896863
}
897864

865+
// AddWitnessCommitment adds the witness commitment as an OP_RETURN outpout
866+
// within the coinbase tx. The raw commitment is returned.
867+
func AddWitnessCommitment(coinbaseTx *btcutil.Tx,
868+
blockTxns []*btcutil.Tx) []byte {
869+
870+
// The witness of the coinbase transaction MUST be exactly 32-bytes
871+
// of all zeroes.
872+
var witnessNonce [blockchain.CoinbaseWitnessDataLen]byte
873+
coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]}
874+
875+
// Next, obtain the merkle root of a tree which consists of the
876+
// wtxid of all transactions in the block. The coinbase
877+
// transaction will have a special wtxid of all zeroes.
878+
witnessMerkleTree := blockchain.BuildMerkleTreeStore(blockTxns,
879+
true)
880+
witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1]
881+
882+
// The preimage to the witness commitment is:
883+
// witnessRoot || coinbaseWitness
884+
var witnessPreimage [64]byte
885+
copy(witnessPreimage[:32], witnessMerkleRoot[:])
886+
copy(witnessPreimage[32:], witnessNonce[:])
887+
888+
// The witness commitment itself is the double-sha256 of the
889+
// witness preimage generated above. With the commitment
890+
// generated, the witness script for the output is: OP_RETURN
891+
// OP_DATA_36 {0xaa21a9ed || witnessCommitment}. The leading
892+
// prefix is referred to as the "witness magic bytes".
893+
witnessCommitment := chainhash.DoubleHashB(witnessPreimage[:])
894+
witnessScript := append(blockchain.WitnessMagicBytes, witnessCommitment...)
895+
896+
// Finally, create the OP_RETURN carrying witness commitment
897+
// output as an additional output within the coinbase.
898+
commitmentOutput := &wire.TxOut{
899+
Value: 0,
900+
PkScript: witnessScript,
901+
}
902+
coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut,
903+
commitmentOutput)
904+
905+
return witnessCommitment
906+
}
907+
898908
// UpdateBlockTime updates the timestamp in the header of the passed block to
899909
// the current time while taking into account the median time of the last
900910
// several blocks to ensure the new time is after that time per the chain

0 commit comments

Comments
 (0)