diff --git a/03-Protocol-Overview.md b/03-Protocol-Overview.md index 3172ca9..bb49eab 100644 --- a/03-Protocol-Overview.md +++ b/03-Protocol-Overview.md @@ -286,3 +286,65 @@ Upon receiving the message, the client re-initiates the Noise handshake and uses For security reasons, it is not possible to reconnect to a server with a certificate signed by a different pool authority key. The message intentionally does not contain a **pool public key** and thus cannot be used to reconnect to a different pool. This ensures that an attacker will not be able to redirect hashrate to an arbitrary server should the pool server get compromised and instructed to send reconnects to a new location. + +## 3.7 BIP141 + +[BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) introduced the notion of Segregated Witness (SegWit) into the Bitcoin protocol. + +This deserves some consideration in the Stratum V2 protocol design, mainly because this affects how the Coinbase transaction is serialized across different messages. + +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. + +On a serialized SegWit transaction, the BIP141 fields are: +- marker +- flag +- witness count +- witness length +- witness + +The presence or absence of these fields on a serialized Coinbase has important implications on the Stratum V2 protocol. More specifically, the following messages are affected: +- `NewExtendedMiningJob` of Mining Protocol +- `DeclareMiningJob` of Job Declaration Protocol +- `SubmitSolution` of Template Distribution Protocol +- `NewTemplate` of Template Distribution Protocol + +### 3.7.1 BIP141 on `NewExtendedMiningJob` + +On the Mining Protocol's `NewExtendedMiningJob` there are two fields affected by BIP141: +- `coinbase_tx_prefix` +- `coinbase_tx_suffix` + +When concatenated with `extranonce_prefix` + `extranonce`, these fields form a serialized Coinbase transaction that is then hashed to produce a `txid`. Together with `merkle_path`, this `txid` +will then form the `merkle_root` of the Block Header. + +In case the Template's Coinbase is a SegWit transaction, BIP141 fields MUST be stripped away from `coinbase_tx_prefix` and `coinbase_tx_suffix`, otherwise clients would be calculating a `merkle_root` with the Coinbase's `wtxid`, which goes against Bitcoin Consensus. + +The server MUST retain the original value of those fields so that it can reconstruct the Coinbase as a SegWit transaction whenever it needs to propagate a block. + +### 3.7.2 BIP141 on `DeclareMiningJob` + +On the Job Declaration Protocol's `DeclareMiningJob` there are two fields affected by BIP141: +- `coinbase_tx_prefix` +- `coinbase_tx_suffix` + +Differently from `NewExtendedMiningJob`, in case the Template's Coinbase is a SegWit transaction, BIP141 fields MUST NOT be stripped from `DeclareMiningJob`'s `coinbase_tx_prefix` and `coinbase_tx_suffix`. + +That's because JDS needs to be able to reconstruct the Coinbase as a SegWit transaction whenever it needs to propagate a block. + +### 3.7.3 BIP141 on `SubmitSolution` + +On the Template Distribution Protocol's `SubmitSolution` there is one field affected by BIP141: +- `coinbase_tx` + +Differently from `NewExtendedMiningJob`, in case the Template's Coinbase is a SegWit transaction, BIP141 fields MUST NOT be stripped from `SubmitSolution`'s `coinbase_tx`. + +That's because the Template Distribution Server would not be able to propagate a block without that data. + +### 3.7.4. BIP141 on `NewTemplate` + +On the Template Distribution Protocol's `NewTemplate` there is one field affected by BIP141: +- `coinbase_tx_outputs` + +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). \ No newline at end of file diff --git a/05-Mining-Protocol.md b/05-Mining-Protocol.md index 2de838c..3e03327 100644 --- a/05-Mining-Protocol.md +++ b/05-Mining-Protocol.md @@ -427,6 +427,8 @@ A proxy MUST translate the message for all downstream channels belonging to the - For a **standard channel**: `extranonce_prefix` - For an **extended channel**: `extranonce_prefix + extranonce (=N bytes)`, where `N` is the negotiated extranonce space for the channel (`OpenMiningChannel.Success.extranonce_size`) +\*If the original coinbase is a SegWit transaction, `coinbase_tx_prefix` and `coinbase_tx_suffix` MUST be stripped of BIP141 fields (marker, flag, witness count, witness length and witness reserved value). + ### 5.3.17 `SetNewPrevHash` (Server -> Client, broadcast) Prevhash is distributed whenever a new block is detected in the network by an upstream node or when a new downstream opens a channel. diff --git a/06-Job-Declaration-Protocol.md b/06-Job-Declaration-Protocol.md index 0474f4c..faf480a 100644 --- a/06-Job-Declaration-Protocol.md +++ b/06-Job-Declaration-Protocol.md @@ -204,6 +204,8 @@ A request sent by JDC that proposes a selected set of transactions to JDS. | coinbase_tx_suffix | B0_64K | Serialized bytes representing the final part of the coinbase transaction (after extranonce) | | tx_ids_list | SEQ0_64K[U256] | List of hashes of the transaction set contained in the template. JDS checks the list against its mempool and requests missing txs via `ProvideMissingTransactions`. Does not include the coinbase transaction (as there is no corresponding full data for it yet). | | excess_data | B0_64K | Extra data which the Pool may require to validate the work (as defined in the Template Distribution Protocol) | +\*Differently from `NewExtendedMiningJob`, if the original coinbase is a SegWit transaction, `coinbase_tx_prefix` and `coinbase_tx_suffix` MUST NOT be stripped of BIP141 fields (marker, flag, witness count, witness length and witness reserved value). + ### 6.4.5 `DeclareMiningJob.Success` (Server -> Client) diff --git a/07-Template-Distribution-Protocol.md b/07-Template-Distribution-Protocol.md index ecda9cb..078b893 100644 --- a/07-Template-Distribution-Protocol.md +++ b/07-Template-Distribution-Protocol.md @@ -47,6 +47,8 @@ The primary template-providing function. Note that the `coinbase_tx_outputs` byt 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). + ## 7.3 `SetNewPrevHash` (Server -> Client) Upon successful validation of a new best block, the server MUST immediately provide a `SetNewPrevHash` message. @@ -118,3 +120,5 @@ Upon finding a coinbase transaction/nonce pair which double-SHA256 hashes at or | header_timestamp | U32 | The nTime field in the block header. This MUST be greater than or equal to the header_timestamp field in the latest SetNewPrevHash message and lower than or equal to that value plus the number of seconds since the receipt of that message. | | header_nonce | U32 | The nonce field in the header | | coinbase_tx | B0_64K | The full serialized coinbase transaction, meeting all the requirements of the NewTemplate message, above | + +\*Differently from `NewExtendedMiningJob`, if the original coinbase is a SegWit transaction, `coinbase_tx` MUST NOT be stripped of BIP141 fields (marker, flag, witness count, witness length and witness reserved value). \ No newline at end of file diff --git a/README.md b/README.md index a2397ca..fdbf8ba 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ This repository contains the Stratum V2 protocol specification. - [3.6.3. `SetupConnection.Error` (Server -> Client)](./03-Protocol-Overview.md#363-setupconnectionerror-server---client) - [3.6.4. `ChannelEndpointChanged` (Server -> Client)](./03-Protocol-Overview.md#364-channelendpointchanged-server---client) - [3.6.5. `Reconnect` (Server -> Client)](./03-Protocol-Overview.md#365-reconnect-server---client) + - [3.7. BIP141](./03-Protocol-Overview.md#37-bip141) + - [3.7.1. BIP141 on `NewExtendedMiningJob`](./03-Protocol-Overview.md#371-bip141-on-newextendedminingjob) + - [3.7.2. BIP141 on `DeclareMiningJob`](./03-Protocol-Overview.md#372-bip141-on-declareminingjob) + - [3.7.3. BIP141 on `SubmitSolution`](./03-Protocol-Overview.md#373-bip141-on-submitsolution) + - [3.7.4. BIP141 on `NewTemplate`](./03-Protocol-Overview.md#374-bip141-on-newtemplate) - [4. Protocol Security](./04-Protocol-Security.md#4-protocol-security) - [4.1. Motivation for Authenticated Encryption with Associated Data](./04-Protocol-Security.md#41-motivation-for-authenticated-encryption-with-associated-data) - [4.2. Motivation for Using the Noise Protocol Framework](./04-Protocol-Security.md#42-motivation-for-using-the-noise-protocol-framework)