Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions 03-Protocol-Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ This deserves some consideration in the Stratum V2 protocol design, mainly becau

For a block that contains any SegWit transactions (in practice almost any non-empty block), the Coinbase transaction MUST have a witness as well as an `OP_RETURN` output carrying the witness commitment. For an empty block, the Coinbase transaction MAY have a witness and the `OP_RETURN` output with the witness commitment anyway.

The `OP_RETURN` output with the witness commitment is provided by Sv2 Template Providers in the `coinbase_tx_outputs` field of `NewTemplate` message.
The `OP_RETURN` output with the witness commitment is provided by Sv2 Template Providers in the `coinbase_tx_outputs` field of `NewTemplate` message. The corresponding Coinbase witness bytes are provided in `NewTemplate.coinbase_witness` (empty when no witness commitment output is present).

On a serialized SegWit transaction, the BIP141 fields are:
- marker
Expand Down Expand Up @@ -367,7 +367,8 @@ That's because the Template Distribution Server would not be able to propagate a

### 3.7.4. BIP141 on `NewTemplate`

On the Template Distribution Protocol's `NewTemplate` there is one field affected by BIP141:
On the Template Distribution Protocol's `NewTemplate` there are two fields affected by BIP141:
- `coinbase_tx_outputs`
- `coinbase_witness`

In case of blocks containing SegWit transactions (and optionally blocks that don't as well), this field carries the `OP_RETURN` output with the witness commitment. The `witness reserved value` (Coinbase witness) used for calculating this witness commitment is assumed to be 32 bytes of `0x00`, as it currently holds no consensus-critical meaning. This [may change in future soft-forks](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#extensible-commitment-structure).
In case a block contains any transactions with witness data, `coinbase_tx_outputs` carries the `OP_RETURN` output with the witness commitment, and `coinbase_witness` carries the exact 32-byte value used in that commitment pre-image. If all transactions in a block do not have witness data, the witness commitment is optional: if omitted, `coinbase_witness` is empty, and if included, `coinbase_witness` carries the exact 32-byte value used in that commitment pre-image. Clients MUST NOT assume `coinbase_witness` is `0x00...00`, as this [may change in future soft-forks](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#extensible-commitment-structure). This value is sent so clients can serialize the coinbase witness consistently with the provided commitment output.
13 changes: 12 additions & 1 deletion 07-Template-Distribution-Protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,23 @@ The primary template-providing function. Note that the `coinbase_tx_outputs` byt
| coinbase_tx_value_remaining | U64 | The value, in satoshis, available for spending in coinbase outputs added by the client. Includes both transaction fees and block subsidy. |
| coinbase_tx_outputs_count | U32 | The number of transaction outputs included in coinbase_tx_outputs |
| coinbase_tx_outputs | B0_64K | Bitcoin transaction outputs to be included as the last outputs in the coinbase transaction |
| coinbase_witness | B0_32 | Coinbase witness bytes. MUST be empty if no witness commitment output is present in `coinbase_tx_outputs`; otherwise MUST contain exactly 32 bytes |

@plebhash plebhash Jun 25, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

during WG call @Fi3 is suggesting we look into potentially usingOPTION[B0_32] instead of B0_32

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no hard opinions from me nor @Fi3

just observation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems more clear to me.

@plebhash plebhash Jun 25, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's a summary of how coinbase_witness description would be worded, according to the two potential types and the two different scenarios (with vs without witness commitment):

OPTION[B0_32] B0_32
✅ WITH witness commitment "MUST NOT be empty, and MUST contain exactly 32 bytes" "MUST contain exactly 32 bytes"
❌ WITHOUT witness commitment "MUST be empty" "MUST be empty"

or as whole description sentences:

B0_32 Coinbase witness bytes. MUST be empty if no witness commitment output is present in coinbase_tx_outputs; otherwise MUST contain exactly 32 bytes
OPTION[B0_32] Coinbase witness bytes. MUST be empty if no witness commitment output is present in coinbase_tx_outputs; otherwise MUST NOT be empty, and MUST contain exactly 32 bytes

@Sjors Sjors Jun 26, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saying "MUST not be empty" makes the text more confusing :-)

With OPTION[B0_32] this should be enough:

Coinbase witness bytes. MUST be empty if no witness commitment output is present in coinbase_tx_outputs; otherwise MUST contain exactly 32 bytes.

Also why not OPTION[U256] so the length is non-ambiguous?

Coinbase witness (32 bytes by consensus rules). MUST be empty if no witness commitment output is present in coinbase_tx_outputs.

@plebhash plebhash Jun 26, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eureka I think OPTION[U256] hits the sweet spot!

it optimally forbids both edge cases without room for interpretation footguns

cc @Fi3

| coinbase_tx_locktime | U32 | The locktime field in the coinbase transaction |
| merkle_path | SEQ0_255[U256] | Merkle path hashes ordered from deepest |

Please note that differently from `SetCustomMiningJob.coinbase_tx_outputs` and `AllocateMiningJobToken.Success.coinbase_tx_outputs`, `NewTemplate.coinbase_tx_outputs` MUST NOT be serialized as a CompactSize-prefixed array. This field must simply carry the ordered sequence of consensus‑serialized outputs, but the number of outputs MUST be inferred from `NewTemplate.coinbase_tx_outputs_count`. This is the equivalent of taking a CompactSize-prefixed array and dropping its (outer) prefix.

Please also note that in case the block contains SegWit transactions (and optionally blocks that don't as well), `NewTemplate.coinbase_tx_outputs` MUST carry the witness commitment. The `witness reserved value` (Coinbase witness) used for calculating this witness commitment is assumed to be 32 bytes of `0x00`, as it currently holds no consensus-critical meaning. This [may change in future soft-forks](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#extensible-commitment-structure).
The full ordered list of coinbase outputs is constructed as `<client-added-outputs> || <NewTemplate.coinbase_tx_outputs>`. Clients MUST NOT reorder or modify outputs from `NewTemplate.coinbase_tx_outputs`.

Please also note that if the block contains any transactions with witness data, `NewTemplate.coinbase_tx_outputs` MUST carry the witness commitment, and `NewTemplate.coinbase_witness` MUST contain exactly 32 bytes equal to the value used in the witness commitment pre-image.

If all transactions in a block do not have witness data, the witness commitment is optional. In this case, the server MAY omit the witness commitment output from `NewTemplate.coinbase_tx_outputs`, and then `NewTemplate.coinbase_witness` MUST be empty. If the server includes a witness commitment output anyway, `NewTemplate.coinbase_witness` MUST contain exactly 32 bytes equal to the value used in the witness commitment pre-image.

Clients MUST NOT assume `NewTemplate.coinbase_witness` is `0x00...00`, as this [may change in future soft-forks](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#extensible-commitment-structure).

`NewTemplate.coinbase_witness` exists so clients can serialize the coinbase input witness in a way that is coherent with the witness commitment output already provided by the server. Clients are not required to recalculate the witness commitment hash.

If `NewTemplate.coinbase_witness` contains 32 bytes, the client MUST serialize the coinbase transaction as SegWit and the coinbase input witness MUST contain exactly one stack element whose bytes are equal to `NewTemplate.coinbase_witness`. If `NewTemplate.coinbase_witness` is empty, the client MUST serialize the coinbase transaction without BIP141 witness fields.

## 7.3 `SetNewPrevHash` (Server -> Client)

Expand Down
Loading