Background
BIP 145 explicitly states:
"Servers MUST NOT include a commitment in the coinbasetxn key on the template. Clients MUST insert the commitment as an additional output at the end of the final generation (coinbase) transaction."
btcd currently violates this requirement. In mining/mining.go line 808, AddWitnessCommitment appends the witness commitment directly to the coinbase transaction. In rpcserver.go line 1814, blockTemplateResult serializes msgBlock.Transactions[0] the same coinbase into CoinbaseTxn, so the commitment is included in the response.
I noticed this while working on PR #2569 which enforces BIP 145 segwit rule requirements in getblocktemplate requests.
Your environment
- Latest master branch of btcd
- Verified on Linux
Steps to reproduce
- Start btcd on a network where segwit is active
- Call
getblocktemplate with coinbasetxn capability and segwit in rules
- Inspect the returned
coinbasetxn field it contains an OP_RETURN output with the witness commitment already included
Relevant code:
mining/mining.go line 808 — AddWitnessCommitment appends commitment to coinbase
rpcserver.go line 1814 — coinbase serialized into coinbasetxn with commitment already present
Expected behaviour
The coinbasetxn field should contain a clean coinbase transaction without the witness commitment. The client is responsible for calculating and appending the commitment as the final output per BIP 145.
Actual behaviour
The coinbasetxn field contains the coinbase transaction with the witness commitment already appended as an OP_RETURN output. A strict BIP 145 compliant client would append a second commitment, producing an invalid block rejected by the network.
Note: fixing this is non-trivial because CheckConnectBlockTemplate requires the commitment to be present internally for validation. A fix would need to strip the commitment before serializing into coinbasetxn while keeping it in the internal template.
Background
BIP 145 explicitly states:
btcd currently violates this requirement. In
mining/mining.goline 808,AddWitnessCommitmentappends the witness commitment directly to the coinbase transaction. Inrpcserver.goline 1814,blockTemplateResultserializesmsgBlock.Transactions[0]the same coinbase intoCoinbaseTxn, so the commitment is included in the response.I noticed this while working on PR #2569 which enforces BIP 145 segwit rule requirements in
getblocktemplaterequests.Your environment
Steps to reproduce
getblocktemplatewithcoinbasetxncapability andsegwitin rulescoinbasetxnfield it contains an OP_RETURN output with the witness commitment already includedRelevant code:
mining/mining.goline 808 —AddWitnessCommitmentappends commitment to coinbaserpcserver.goline 1814 — coinbase serialized intocoinbasetxnwith commitment already presentExpected behaviour
The
coinbasetxnfield should contain a clean coinbase transaction without the witness commitment. The client is responsible for calculating and appending the commitment as the final output per BIP 145.Actual behaviour
The
coinbasetxnfield contains the coinbase transaction with the witness commitment already appended as an OP_RETURN output. A strict BIP 145 compliant client would append a second commitment, producing an invalid block rejected by the network.Note: fixing this is non-trivial because
CheckConnectBlockTemplaterequires the commitment to be present internally for validation. A fix would need to strip the commitment before serializing intocoinbasetxnwhile keeping it in the internal template.