Skip to content

Commit ac0a2bd

Browse files
authored
Merge pull request #162 from plebhash/2025-10-24-group-extended-channels
allow Group Channels to contain Extended Channels
2 parents 3012409 + 57641ed commit ac0a2bd

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

05-Mining-Protocol.md

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ For conversion into Standard Jobs, the Coinbase Transaction is constructed by co
101101

102102
The Coinbase Transaction is then combined with the `merkle_path` of the Extended Job to calculate the `merkle_root` for the Standard Job notification (`NewMiningJob`). Since Standard Jobs are HOM, there's no `extranonce_size` field on the Standard Job notification.
103103

104+
In case of an Extended Job broadcast to a Group Channel, its `coinbase_tx_prefix` carries the transaction field `scriptSig length`. It follows that every Standard and/or Extended Channel that belongs to the same Group Channel MUST have the exact same full Extended Extranonce size, because the coinbase transaction they are working on MUST have the same `scriptSig length` that is broadcast to the Group Channel.
105+
104106
### 5.1.3 Future Job
105107

106108
A Job with an empty template or speculated non-empty template can be sent in advance to speedup Job distribution when a new block is found on the network.
@@ -177,10 +179,12 @@ The size of search space for an Extended Channel is `2^(nonce_bits + version_rol
177179

178180
### 5.2.3 Group Channel
179181

180-
Standard channels opened within one particular connection can be grouped together to be addressable by a common communication group channel.
182+
Mining and/or Standard Channels opened within one particular connection can be grouped together to be addressable by a common communication group channel.
183+
184+
Every mining channel is a member of a group identified by its `group_channel_id`.
185+
Group Channel ID namespace is the same as Mining Channel ID namespace on a particular connection. In other words, there must never be a Group Channel whose `group_channel_id` is identical to some `channel_id` of some Standard or Extended Channel within the context of the same connection.
181186

182-
Whenever a Standard Channel is created, it is always put into some Group Channel identified by its `group_channel_id`.
183-
Group Channel ID namespace is the same as Standard Channel ID namespace on a particular connection.
187+
All channels under the same Group Channel (Extended and Standard) MUST have the exact same size for the full Extended Extranonce (`extranonce_prefix` for Standard Channels, or `extranonce_prefix` + `extranonce` for Extended Channels).
184188

185189
## 5.3 Mining Protocol Messages
186190

@@ -257,6 +261,7 @@ Sent as a response for opening an extended channel.
257261
| target | U256 | Initial target for the mining channel |
258262
| extranonce_size | U16 | Extranonce size (in bytes) set for the channel |
259263
| extranonce_prefix | B0_32 | Bytes used as implicit first part of extranonce |
264+
| group_channel_id | U32 | Group channel into which the new channel belongs. See SetGroupChannel for details. |
260265

261266
### 5.3.6 `OpenMiningChannel.Error` (Server -> Client)
262267

@@ -312,6 +317,8 @@ A proxy MUST send this message on behalf of all opened channels from a downstrea
312317
If a proxy is operating in channel aggregating mode (translating downstream channels into aggregated extended upstream channels), it MUST send an `UpdateChannel` message when it receives `CloseChannel` or connection closure from a downstream connection.
313318
In general, proxy servers MUST keep the upstream node notified about the real state of the downstream channels.
314319

320+
If `channel_id` is addressing a group channel, all channels belonging to such group MUST be closed.
321+
315322
### 5.3.10 `SetExtranoncePrefix` (Server -> Client)
316323

317324
Changes downstream node’s extranonce prefix.
@@ -404,16 +411,14 @@ The whole search space of the job is owned by the specified channel.
404411
If the `min_ntime` field is set to some nTime, the client MUST start to mine on the new job as soon as possible after receiving this message.
405412

406413
For a **group channel**:
407-
This is a broadcast variant of `NewMiningJob` message with the `merkle_root` field replaced by `merkle_path` and coinbase transaction prefix and suffix, for further traffic optimization.
408-
The Merkle root is then defined deterministically for each channel by the common `merkle_path` and unique `extranonce_prefix` serialized into the coinbase.
409-
The full coinbase is then constructed as follows: `coinbase_tx_prefix + extranonce_prefix + coinbase_tx_suffix`.
414+
This acts as a broadcast message that distributes work to all channels under the same group with one single message, instead of one per channel.
410415

411416
The proxy MAY transform this multicast variant for downstream standard channels into `NewMiningJob` messages by computing the derived Merkle root for them.
412-
A proxy MUST translate the message for all downstream channels belonging to the group which don’t signal that they accept extended mining jobs in the `SetupConnection` message (intended and expected behavior for end mining devices).
417+
A proxy MUST translate the message into `NewMiningJob` for all downstream standard channels belonging to the group in case the `SetupConnection` message had the `REQUIRES_STANDARD_JOB` flag set (intended and expected behavior for end mining devices).
413418

414419
| Field Name | Data Type | Description |
415420
| ----------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
416-
| channel_id | U32 | For a group channel, the message is broadcasted to all standard channels belonging to the group. Otherwise, it is addressed to the specified extended channel. |
421+
| channel_id | U32 | For a group channel, the message is broadcasted to all mining channels belonging to the group. Otherwise, it is addressed to the specified extended channel. |
417422
| job_id | U32 | Server’s identification of the mining job |
418423
| min_ntime | OPTION[u32] | Smallest nTime value available for hashing for the new mining job. An empty value indicates this is a future job to be activated once a SetNewPrevHash message is received with a matching job_id. This SetNewPrevHash message provides the new prev_hash and min_ntime. If the min_ntime value is set, this mining job is active and miner must start mining on it immediately. In this case, the new mining job uses the prev_hash from the last received SetNewPrevHash message. immediately. |
419424
| version | U32 | Valid version field that reflects the current network consensus |
@@ -429,11 +434,35 @@ A proxy MUST translate the message for all downstream channels belonging to the
429434

430435
\*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).
431436

437+
The merkle root is then calculated as follows:
438+
439+
```
440+
# Build the coinbase transaction
441+
coinbase_tx = concatenate(
442+
coinbase_tx_prefix,
443+
extranonce_prefix,
444+
extranonce, # null if standard channel
445+
coinbase_tx_suffix
446+
)
447+
448+
# txid of the coinbase transaction (not wtxid, as coinbase_tx_prefix and coinbase_tx_suffix were stripped of BIP141)
449+
coinbase_txid = SHA256(SHA256(coinbase_tx))
450+
451+
# Compute the Merkle root by folding over the Merkle path
452+
raw_merkle_root = coinbase_txid
453+
for each merkle_leaf in merkle_path:
454+
data = concatenate(raw_merkle_root, merkle_leaf as little_endian_bytes)
455+
raw_merkle_root = SHA256(SHA256(data))
456+
457+
# Interpret the final 32-byte hash as a 256-bit integer in little-endian form
458+
merkle_root = Uint256(little_endian_bytes = raw_merkle_root)
459+
```
460+
432461
### 5.3.17 `SetNewPrevHash` (Server -> Client, broadcast)
433462

434463
Prevhash is distributed whenever a new block is detected in the network by an upstream node or when a new downstream opens a channel.
435464

436-
This message MAY be shared by all downstream nodes (sent only once to each channel group).
465+
This message MAY be shared by all downstream nodes (sent only once to each group channel).
437466
Clients MUST immediately start to mine on the provided prevhash.
438467
When a client receives this message, only the job referenced by Job ID is valid.
439468
The remaining jobs already queued by the client have to be made invalid.
@@ -450,7 +479,8 @@ Note: There is no need for block height in this message.
450479

451480
### 5.3.18 `SetCustomMiningJob` (Client -> Server)
452481

453-
Can be sent only on extended channel.
482+
Can be sent only on extended or group channel. If the group channel contains standard channels, the server MUST ignore those.
483+
454484
`SetupConnection.flags` MUST contain `REQUIRES_WORK_SELECTION` flag (work selection feature successfully declared).
455485

456486
This message signals that JDC expects to be rewarded for working on a Custom Job.
@@ -525,18 +555,19 @@ When `SetTarget` is sent to a group channel, the maximum target is applicable to
525555

526556
### 5.3.22 `SetGroupChannel` (Server -> Client)
527557

528-
Every standard channel is a member of a group of standard channels, addressed by the upstream server's provided identifier.
529-
The group channel is used mainly for efficient job distribution to multiple standard channels at once.
558+
The group channel is used mainly for efficient job distribution to multiple mining channels (either standard and/or extended).
530559

531-
If we want to allow different jobs to be served to different standard channels (e.g. because of different [BIP 8](https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki) version bits) and still be able to distribute the work by sending `NewExtendendedMiningJob` instead of a repeated `NewMiningJob`, we need a more fine-grained grouping for standard channels.
560+
If we want to allow different jobs to be served to different mining channels (e.g. because of different [BIP 8](https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki) version bits) and still be able to distribute the work by sending `NewExtendendedMiningJob` instead of a repeated `NewMiningJob` and/or `NewExtendedMiningJob`, we need a more fine-grained grouping for standard channels.
532561

533-
This message associates a set of standard channels with a group channel.
562+
This message associates a set of mining channels with a group channel.
534563
A channel (identified by particular ID) becomes a group channel when it is used by this message as `group_channel_id`.
535564
The server MUST ensure that a group channel has a unique channel ID within one connection. Channel reinterpretation is not allowed.
536565

537566
This message can be sent only to connections that don’t have `REQUIRES_STANDARD_JOBS` flag in `SetupConnection`.
538567

539568
| Field Name | Data Type | Description |
540569
| ---------------- | ------------- | ----------------------------------------------------------------------------------------- |
541-
| group_channel_id | U32 | Identifier of the group where the standard channel belongs |
542-
| channel_ids | SEQ0_64K[U32] | A sequence of opened standard channel IDs, for which the group channel is being redefined |
570+
| group_channel_id | U32 | Identifier of the group where the standard or extended channel belongs |
571+
| channel_ids | SEQ0_64K[U32] | A sequence of opened standard or extended channel IDs, for which the group channel is being redefined |
572+
573+
All channels under the same Group Channel (Extended and Standard) MUST have the exact same size for the full Extended Extranonce (`extranonce_prefix` for Standard Channels, or `extranonce_prefix` + `extranonce` for Extended Channels).

0 commit comments

Comments
 (0)