forked from ethereum/consensus-specs
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
548 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
# ePBS -- Networking | ||
|
||
This document contains the consensus-layer networking specification for ePBS. | ||
|
||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* | ||
|
||
- [Modification in ePBS](#modification-in-epbs) | ||
- [Preset](#preset) | ||
- [Containers](#containers) | ||
- [`BlobSidecar`](#blobsidecar) | ||
- [Helpers](#helpers) | ||
- [Modified `verify_blob_sidecar_inclusion_proof`](#modified-verify_blob_sidecar_inclusion_proof) | ||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub) | ||
- [Topics and messages](#topics-and-messages) | ||
- [Global topics](#global-topics) | ||
- [`beacon_block`](#beacon_block) | ||
- [`execution_payload`](#execution_payload) | ||
- [`payload_attestation_message`](#payload_attestation_message) | ||
- [`execution_payload_header`](#execution_payload_header) | ||
- [`inclusion_list`](#inclusion_list) | ||
- [Transitioning the gossip](#transitioning-the-gossip) | ||
- [The Req/Resp domain](#the-reqresp-domain) | ||
- [Messages](#messages) | ||
- [BeaconBlocksByRange v3](#beaconblocksbyrange-v3) | ||
- [BeaconBlocksByRoot v3](#beaconblocksbyroot-v3) | ||
- [BlobSidecarsByRoot v2](#blobsidecarsbyroot-v2) | ||
- [ExecutionPayloadEnvelopeByRoot v1](#executionpayloadenvelopebyroot-v1) | ||
|
||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
|
||
## Modification in ePBS | ||
|
||
### Preset | ||
|
||
*[Modified in ePBS]* | ||
|
||
| Name | Value | Description | | ||
|------------------------------------------|-----------------------------------|---------------------------------------------------------------------| | ||
| `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` | TODO: Compute it when the spec stabilizes | Merkle proof depth for the `blob_kzg_commitments` list item | | ||
| `KZG_GENERALIZED_INDEX_PREFIX` | TODO: Compute it when the spec stabilizes | Generalized index for the first item in the `blob_kzg_commitments` list | | ||
|
||
### Containers | ||
|
||
#### `BlobSidecar` | ||
|
||
The `BlobSidecar` container is modified indirectly because the constant `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` is modified. | ||
|
||
```python | ||
class BlobSidecar(Container): | ||
index: BlobIndex # Index of blob in block | ||
blob: Blob | ||
kzg_commitment: KZGCommitment | ||
kzg_proof: KZGProof # Allows for quick verification of kzg_commitment | ||
signed_block_header: SignedBeaconBlockHeader | ||
kzg_commitment_inclusion_proof: Vector[Bytes32, KZG_COMMITMENT_INCLUSION_PROOF_DEPTH] | ||
``` | ||
|
||
#### Helpers | ||
|
||
##### Modified `verify_blob_sidecar_inclusion_proof` | ||
|
||
`verify_blob_sidecar_inclusion_proof` is modified in ePBS to account for the fact that the kzg commitments are included in the `ExecutionPayloadEnvelope` and no longer in the beacon block body. | ||
|
||
```python | ||
def verify_blob_sidecar_inclusion_proof(blob_sidecar: BlobSidecar) -> bool: | ||
# hardcoded here because the block does not include the commitments but only their root. | ||
gindex = GeneralizedIndex(KZG_GENERALIZED_INDEX_PREFIX + blob_sidecar.index) | ||
|
||
return is_valid_merkle_branch( | ||
leaf=blob_sidecar.kzg_commitment.hash_tree_root(), | ||
branch=blob_sidecar.kzg_commitment_inclusion_proof, | ||
depth=KZG_COMMITMENT_INCLUSION_PROOF_DEPTH, | ||
index=gindex, | ||
root=blob_sidecar.signed_block_header.message.body_root, | ||
) | ||
``` | ||
|
||
### The gossip domain: gossipsub | ||
|
||
Some gossip meshes are upgraded in the fork of ePBS to support upgraded types. | ||
|
||
#### Topics and messages | ||
|
||
Topics follow the same specification as in prior upgrades. | ||
|
||
The `beacon_block` topic is updated to support the modified type | ||
| Name | Message Type | | ||
| --- | --- | | ||
| `beacon_block` | `SignedBeaconBlock` (modified) | | ||
|
||
The new topics along with the type of the `data` field of a gossipsub message are given in this table: | ||
|
||
| Name | Message Type | | ||
|-------------------------------|------------------------------------------------------| | ||
| `execution_payload_header` | `SignedExecutionPayloadHeader` [New in ePBS] | | ||
| `execution_payload` | `SignedExecutionPayloadEnvelope` [New in ePBS] | | ||
| `payload_attestation_message` | `PayloadAttestationMessage` [New in ePBS] | | ||
| `inclusion_list` | `InclusionList` [New in ePBS] | | ||
|
||
##### Global topics | ||
|
||
ePBS introduces new global topics for execution header, execution payload, payload attestation and inclusion list. | ||
|
||
###### `beacon_block` | ||
|
||
The *type* of the payload of this topic changes to the (modified) `SignedBeaconBlock` found in ePBS spec. | ||
|
||
There are no new validations for this topic. | ||
|
||
###### `execution_payload` | ||
|
||
This topic is used to propagate execution payload messages as `SignedExecutionPayloadEnvelope`. | ||
|
||
The following validations MUST pass before forwarding the `signed_execution_payload_envelope` on the network, assuming the alias `envelope = signed_execution_payload_envelope.message`, `payload = payload_envelope.payload`: | ||
|
||
- _[IGNORE]_ The envelope's block root `envelope.block_root` has been seen (via both gossip and non-gossip sources) (a client MAY queue payload for processing once the block is retrieved). | ||
|
||
Let `block` be the block with `envelope.beacon_block_root`. | ||
Let `header` alias `block.body.signed_execution_payload_header.message` (notice that this can be obtained from the `state.signed_execution_payload_header`) | ||
- _[REJECT]_ `block` passes validation. | ||
- _[REJECT]_ `envelope.builder_index == header.builder_index` | ||
- _[REJECT]_ `payload.block_hash == header.block_hash` | ||
- _[REJECT]_ `hash_tree_root(payload.blob_kzg_commitments) == header.blob_kzg_commitments_root` | ||
- _[REJECT]_ The builder signature, `signed_execution_payload_envelope.signature`, is valid with respect to the builder's public key. | ||
|
||
###### `payload_attestation_message` | ||
|
||
This topic is used to propagate signed payload attestation message. | ||
|
||
The following validations MUST pass before forwarding the `payload_attestation_message` on the network, assuming the alias `data = payload_attestation_message.data`: | ||
|
||
- _[IGNORE]_ `data.slot` is the current slot. | ||
- _[REJECT]_ `data.payload_status < PAYLOAD_INVALID_STATUS` | ||
- _[IGNORE]_ The attestation's `data.beacon_block_root` has been seen (via both gossip and non-gossip sources) (a client MAY queue attestation for processing once the block is retrieved. Note a client might want to request payload after). | ||
- _[REJECT]_ The validator index is within the payload committee in `get_ptc(state, data.slot)`. For the current's slot head state. | ||
- _[REJECT]_ The signature of `payload_attestation_message.signature` is valid with respect to the validator index. | ||
|
||
###### `execution_payload_header` | ||
|
||
This topic is used to propagate signed bids as `SignedExecutionPayloadHeader`. | ||
|
||
The following validations MUST pass before forwarding the `signed_execution_payload_header` on the network, assuming the alias `header = signed_execution_payload_header.message`: | ||
|
||
- _[IGNORE]_ this is the first signed bid seen with a valid signature from the given builder for this slot. | ||
- _[REJECT]_ The signed builder bid, `header.builder_index` is a valid and non-slashed builder index in state. | ||
- _[IGNORE]_ The signed builder bid value, `header.value`, is less or equal than the builder's balance in state. i.e. `MIN_BUILDER_BALANCE + header.value < state.builder_balances[header.builder_index]`. | ||
- _[IGNORE]_ `header.parent_block_root` is a known block root in fork choice. | ||
- _[IGNORE]_ `header.slot` is the current slot or the next slot. | ||
- _[REJECT]_ The builder signature, `signed_execution_payload_header_envelope.signature`, is valid with respect to the `header_envelope.builder_index`. | ||
|
||
###### `inclusion_list` | ||
|
||
This topic is used to propagate inclusion lists as `InclusionList` objects. | ||
|
||
The following validations MUST pass before forwarding the `inclusion_list` on the network, assuming the alias `signed_summary = inclusion_list.signed_summary`, `summary = signed_summary.message`: | ||
|
||
- _[IGNORE]_ The inclusion list is for the current slot or the next slot (a client MAY queue future inclusion lists for processing at the appropriate slot). | ||
- _[IGNORE]_ The inclusion list is the first inclusion list with valid signature received for the proposer for the slot, `inclusion_list.slot`. | ||
- _[REJECT]_ The inclusion list transactions `inclusion_list.transactions` length is less or equal than `MAX_TRANSACTIONS_PER_INCLUSION_LIST`. | ||
- _[REJECT]_ The inclusion list summary has the same length of transactions `len(summary.summary) == len(inclusion_list.transactions)`. | ||
- _[REJECT]_ The summary signature, `signed_summary.signature`, is valid with respect to the `proposer_index` pubkey. | ||
- _[REJECT]_ The summary is proposed by the expected proposer_index for the summary's slot in the context of the current shuffling (defined by parent_root/slot). If the proposer_index cannot immediately be verified against the expected shuffling, the inclusion list MAY be queued for later processing while proposers for the summary's branch are calculated -- in such a case do not REJECT, instead IGNORE this message. | ||
|
||
#### Transitioning the gossip | ||
|
||
See gossip transition details found in the [Altair document](../altair/p2p-interface.md#transitioning-the-gossip) for | ||
details on how to handle transitioning gossip topics for this upgrade. | ||
|
||
### The Req/Resp domain | ||
|
||
#### Messages | ||
|
||
##### BeaconBlocksByRange v3 | ||
|
||
**Protocol ID:** `/eth2/beacon_chain/req/beacon_blocks_by_range/3/` | ||
|
||
[0]: # (eth2spec: skip) | ||
|
||
| `fork_version` | Chunk SSZ type | | ||
|--------------------------|-------------------------------| | ||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` | | ||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` | | ||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` | | ||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` | | ||
| `DENEB_FORK_VERSION` | `deneb.SignedBeaconBlock` | | ||
| `EPBS_FORK_VERSION` | `epbs.SignedBeaconBlock` | | ||
|
||
##### BeaconBlocksByRoot v3 | ||
|
||
**Protocol ID:** `/eth2/beacon_chain/req/beacon_blocks_by_root/3/` | ||
|
||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`: | ||
|
||
[1]: # (eth2spec: skip) | ||
|
||
| `fork_version` | Chunk SSZ type | | ||
|--------------------------|-------------------------------| | ||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` | | ||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` | | ||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` | | ||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` | | ||
| `DENEB_FORK_VERSION` | `deneb.SignedBeaconBlock` | | ||
| `EPBS_FORK_VERSION` | `epbs.SignedBeaconBlock` | | ||
|
||
|
||
##### BlobSidecarsByRoot v2 | ||
|
||
**Protocol ID:** `/eth2/beacon_chain/req/blob_sidecars_by_root/2/` | ||
|
||
[1]: # (eth2spec: skip) | ||
|
||
| `fork_version` | Chunk SSZ type | | ||
|--------------------------|-------------------------------| | ||
| `DENEB_FORK_VERSION` | `deneb.BlobSidecar` | | ||
| `EPBS_FORK_VERSION` | `epbs.BlobSidecar` | | ||
|
||
|
||
##### ExecutionPayloadEnvelopeByRoot v1 | ||
|
||
**Protocol ID:** `/eth2/beacon_chain/req/execution_payload_envelope_by_root/1/` | ||
|
||
The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`: | ||
|
||
[1]: # (eth2spec: skip) | ||
|
||
| `fork_version` | Chunk SSZ type | | ||
|---------------------|---------------------------------------| | ||
| `EPBS_FORK_VERSION` | `epbs.SignedExecutionPayloadEnvelope` | | ||
|
||
Request Content: | ||
|
||
``` | ||
( | ||
List[Root, MAX_REQUEST_PAYLOAD] | ||
) | ||
``` | ||
|
||
Response Content: | ||
|
||
``` | ||
( | ||
List[SignedExecutionPayloadEnvelope, MAX_REQUEST_PAYLOAD] | ||
) | ||
``` | ||
Requests execution payload envelope by `signed_execution_payload_envelope.message.block_root`. The response is a list of SignedExecutionPayloadEnvelope whose length is less than or equal to the number of requested execution payload envelopes. It may be less in the case that the responding peer is missing payload envelopes. | ||
|
||
No more than MAX_REQUEST_PAYLOAD may be requested at a time. | ||
|
||
ExecutionPayloadEnvelopeByRoot is primarily used to recover recent execution payload envelope (e.g. when receiving a payload attestation with revealed status as true but never received a payload). | ||
|
||
The request MUST be encoded as an SSZ-field. | ||
|
||
The response MUST consist of zero or more response_chunk. Each successful response_chunk MUST contain a single SignedExecutionPayloadEnvelope payload. | ||
|
||
Clients MUST support requesting payload envelopes since the latest finalized epoch. | ||
|
||
Clients MUST respond with at least one payload envelope, if they have it. Clients MAY limit the number of payload envelopes in the response. |
Oops, something went wrong.