Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP4844: couple beacon block and blob sidecar for p2p #3046

Merged
merged 7 commits into from
Oct 26, 2022
Merged
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
47 changes: 19 additions & 28 deletions specs/eip4844/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ The specification of these changes continues in the same format as the network s
- [Containers](#containers)
- [`BlobsSidecar`](#blobssidecar)
- [`SignedBlobsSidecar`](#signedblobssidecar)
- [`SignedBeaconBlockAndBlobsSidecar`](#signedbeaconblockandblobssidecar)
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
- [Topics and messages](#topics-and-messages)
- [Global topics](#global-topics)
- [`beacon_block`](#beacon_block)
- [`blobs_sidecar`](#blobs_sidecar)
- [`beacon_block_and_blobs_sidecar`](#beacon_block_and_blobs_sidecar)
- [Transitioning the gossip](#transitioning-the-gossip)
- [The Req/Resp domain](#the-reqresp-domain)
- [Messages](#messages)
Expand Down Expand Up @@ -58,6 +58,14 @@ class SignedBlobsSidecar(Container):
signature: BLSSignature
```

### `SignedBeaconBlockAndBlobsSidecar`

```python
class SignedBeaconBlockAndBlobsSidecar(Container):
beacon_block: SignedBeaconBlock
blobs_sidecar: BlobsSidecar
```

## The gossip domain: gossipsub

Some gossip meshes are upgraded in the fork of EIP4844 to support upgraded types.
Expand All @@ -75,47 +83,30 @@ The new topics along with the type of the `data` field of a gossipsub message ar

| Name | Message Type |
| - | - |
| `beacon_block` | `SignedBeaconBlock` (modified) |
| `blobs_sidecar` | `SignedBlobsSidecar` (new) |
| `beacon_block_and_blobs_sidecar` | `SignedBeaconBlockAndBlobsSidecar` (new) |

Note that the `ForkDigestValue` path segment of the topic separates the old and the new `beacon_block` topics.

#### Global topics

EIP4844 changes the type of the global beacon block topic and introduces a new global topic for blobs-sidecars.
EIP4844 introduces a new global topic for beacon block and blobs-sidecars.

##### `beacon_block`
##### `beacon_block_and_blobs_sidecar`

The *type* of the payload of this topic changes to the (modified) `SignedBeaconBlock` found in EIP4844.
This topic is used to propagate new signed and coupled beacon blocks and blobs sidecars to all nodes on the networks.

In addition to the gossip validations for this topic from prior specifications,
the following validations MUST pass before forwarding the `signed_beacon_block` on the network.
Alias `block = signed_beacon_block.message`, `execution_payload = block.body.execution_payload`.
The following validations MUST pass before forwarding the `signed_beacon_block_and_blobs_sidecar` on the network.
Alias `signed_beacon_block = signed_beacon_block_and_blobs_sidecar.beacon_block`, `block = signed_beacon_block.message`, `execution_payload = block.body.execution_payload`.
- _[REJECT]_ The KZG commitments of the blobs are all correctly encoded compressed BLS G1 Points.
-- i.e. `all(bls.KeyValidate(commitment) for commitment in block.body.blob_kzg_commitments)`
- _[REJECT]_ The KZG commitments correspond to the versioned hashes in the transactions list.
-- i.e. `verify_kzg_commitments_against_transactions(block.body.execution_payload.transactions, block.body.blob_kzg_commitments)`

##### `blobs_sidecar`

This topic is used to propagate data blobs included in any given beacon block.

The following validations MUST pass before forwarding the `signed_blobs_sidecar` on the network;
Alias `sidecar = signed_blobs_sidecar.message`.
- _[IGNORE]_ the `sidecar.beacon_block_slot` is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `sidecar.beacon_block_slot == current_slot`.
Alias `sidecar = signed_beacon_block_and_blobs_sidecar.blobs_sidecar`.
- _[IGNORE]_ the `sidecar.beacon_block_slot` is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `sidecar.beacon_block_slot == block.slot`.
- _[REJECT]_ the `sidecar.blobs` are all well formatted, i.e. the `BLSFieldElement` in valid range (`x < BLS_MODULUS`).
- _[REJECT]_ The KZG proof is a correctly encoded compressed BLS G1 Point -- i.e. `bls.KeyValidate(blobs_sidecar.kzg_aggregated_proof)`
- _[REJECT]_ the beacon proposer signature, `signed_blobs_sidecar.signature`, is valid -- i.e.
- Let `domain = get_domain(state, DOMAIN_BLOBS_SIDECAR, sidecar.beacon_block_slot // SLOTS_PER_EPOCH)`
- Let `signing_root = compute_signing_root(sidecar, domain)`
- Verify `bls.Verify(proposer_pubkey, signing_root, signed_blobs_sidecar.signature) is True`,
where `proposer_pubkey` is the pubkey of the beacon block proposer of `sidecar.beacon_block_slot`
- _[IGNORE]_ The sidecar is the first sidecar with valid signature received for the `(proposer_index, sidecar.beacon_block_slot)` combination,
where `proposer_index` is the validator index of the beacon block proposer of `sidecar.beacon_block_slot`

Note that a sidecar may be propagated before or after the corresponding beacon block.

Once both sidecar and beacon block are received, `validate_blobs_sidecar` can unlock the data-availability fork-choice dependency.
Once the sidecar and beacon block are received together, `validate_blobs_sidecar` can unlock the data-availability fork-choice dependency.

### Transitioning the gossip

Expand Down
39 changes: 17 additions & 22 deletions specs/eip4844/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
- [`compute_proof_from_blobs`](#compute_proof_from_blobs)
- [`get_blobs_and_kzg_commitments`](#get_blobs_and_kzg_commitments)
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
- [Block proposal](#block-proposal)
- [Block and sidecar proposal](#block-and-sidecar-proposal)
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
- [Blob KZG commitments](#blob-kzg-commitments)
- [Beacon Block publishing time](#beacon-block-publishing-time)
- [Constructing the `SignedBeaconBlockAndBlobsSidecar`](#constructing-the-signedbeaconblockandblobssidecar)
- [Block](#block)
- [Sidecar](#sidecar)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
Expand Down Expand Up @@ -192,9 +194,9 @@ def get_blobs_and_kzg_commitments(payload_id: PayloadId) -> Tuple[Sequence[BLSFi
## Beacon chain responsibilities

All validator responsibilities remain unchanged other than those noted below.
Namely, the blob handling and the addition of `BlobsSidecar`.
Namely, the blob handling and the addition of `SignedBeaconBlockAndBlobsSidecar`.

### Block proposal
### Block and sidecar proposal

#### Constructing the `BeaconBlockBody`

Expand All @@ -218,13 +220,16 @@ def validate_blobs_and_kzg_commitments(execution_payload: ExecutionPayload,

3. If valid, set `block.body.blob_kzg_commitments = blob_kzg_commitments`.

Note that the `blobs` should be held with the block in preparation of publishing.
Without the `blobs`, the published block will effectively be ignored by honest validators.
#### Constructing the `SignedBeaconBlockAndBlobsSidecar`
To construct a `SignedBeaconBlockAndBlobsSidecar`, a `signed_beacon_block_and_blobs_sidecar` is defined with the necessary context for block and sidecar proposal.

### Beacon Block publishing time
##### Block
Set `signed_beacon_block_and_blobs_sidecar.beacon_block = block` where `block` is obtained above.

Before publishing a prepared beacon block proposal, the corresponding blobs are packaged into a sidecar object for distribution to the network:
##### Sidecar
Coupled with block, the corresponding blobs are packaged into a sidecar object for distribution to the network.

Set `signed_beacon_block_and_blobs_sidecar.blobs_sidecar = sidecar` where `sidecar` is obtained from:
```python
def get_blobs_sidecar(block: BeaconBlock, blobs: Sequence[Blob]) -> BlobsSidecar:
return BlobsSidecar(
Expand All @@ -235,20 +240,10 @@ def get_blobs_sidecar(block: BeaconBlock, blobs: Sequence[Blob]) -> BlobsSidecar
)
```

And then signed:
This `signed_beacon_block_and_blobs_sidecar` is then published to the global `beacon_block_and_blobs_sidecar` topic.

```python
def get_signed_blobs_sidecar(state: BeaconState, blobs_sidecar: BlobsSidecar, privkey: int) -> SignedBlobsSidecar:
domain = get_domain(state, DOMAIN_BLOBS_SIDECAR, blobs_sidecar.beacon_block_slot // SLOTS_PER_EPOCH)
signing_root = compute_signing_root(blobs_sidecar, domain)
signature = bls.Sign(privkey, signing_root)
return SignedBlobsSidecar(message=blobs_sidecar, signature=signature)
```

This `signed_blobs_sidecar` is then published to the global `blobs_sidecar` topic as soon as the `signed_beacon_block` is published.

After publishing the sidecar peers on the network may request the sidecar through sync-requests, or a local user may be interested.
The validator MUST hold on to blobs for `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` epochs and serve when capable,
After publishing the peers on the network may request the sidecar through sync-requests, or a local user may be interested.
The validator MUST hold on to sidecars for `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` epochs and serve when capable,
to ensure the data-availability of these blobs throughout the network.

After `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` nodes MAY prune the blobs and/or stop serving them.
After `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` nodes MAY prune the sidecars and/or stop serving them.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
get_sample_opaque_tx,
get_sample_blob,
)
from eth2spec.test.helpers.keys import privkeys


@with_eip4844_and_later
Expand All @@ -38,8 +37,6 @@ def _run_validate_blobs_sidecar_test(spec, state, blob_count):
state_transition_and_sign_block(spec, state, block)

blobs_sidecar = spec.get_blobs_sidecar(block, blobs)
privkey = privkeys[1]
spec.get_signed_blobs_sidecar(state, blobs_sidecar, privkey)
Comment on lines -41 to -42
Copy link
Contributor

Choose a reason for hiding this comment

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

ah right, it should have been in another test case + verification 😅

expected_commitments = [spec.blob_to_kzg_commitment(blobs[i]) for i in range(blob_count)]
spec.validate_blobs_sidecar(block.slot, block.hash_tree_root(), expected_commitments, blobs_sidecar)

Expand Down