From 62e6a30ec1237db3f3d9d294a409d88cdc1fe1d8 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 13 Nov 2024 13:42:15 +0700 Subject: [PATCH 1/5] Add `BLOB_SIDECAR_SUBNET_COUNT_EIP7594`, `MAX_BLOBS_PER_BLOCK_EIP7594`, and `MAX_REQUEST_BLOB_SIDECARS_EIP7594` --- configs/mainnet.yaml | 4 + configs/minimal.yaml | 4 + specs/_features/eip7594/beacon-chain.md | 141 +++++++++++++++++++++++ specs/_features/eip7594/p2p-interface.md | 84 ++++++++++++++ specs/deneb/beacon-chain.md | 2 +- 5 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 specs/_features/eip7594/beacon-chain.md diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index 56c20a439c..36b4db4123 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -165,6 +165,10 @@ DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 SAMPLES_PER_SLOT: 8 CUSTODY_REQUIREMENT: 4 +BLOB_SIDECAR_SUBNET_COUNT_EIP7594: 8 +MAX_BLOBS_PER_BLOCK_EIP7594: 8 +# `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_EIP7594` +MAX_REQUEST_BLOB_SIDECARS_EIP7594: 1024 # [New in Electra:EIP7251] MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000 # 2**7 * 10**9 (= 128,000,000,000) diff --git a/configs/minimal.yaml b/configs/minimal.yaml index a2b4f2e736..ae19518af7 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -164,6 +164,10 @@ DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 SAMPLES_PER_SLOT: 8 CUSTODY_REQUIREMENT: 4 +BLOB_SIDECAR_SUBNET_COUNT_EIP7594: 8 +MAX_BLOBS_PER_BLOCK_EIP7594: 8 +# `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_EIP7594` +MAX_REQUEST_BLOB_SIDECARS_EIP7594: 1024 # [New in Electra:EIP7251] MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000 # 2**6 * 10**9 (= 64,000,000,000) diff --git a/specs/_features/eip7594/beacon-chain.md b/specs/_features/eip7594/beacon-chain.md new file mode 100644 index 0000000000..bf980b840d --- /dev/null +++ b/specs/_features/eip7594/beacon-chain.md @@ -0,0 +1,141 @@ +# EIP7594 -- The Beacon Chain + +**Notice**: This document is a work-in-progress for researchers and implementers. + +## Table of contents + + + + + +- [Introduction](#introduction) +- [Configuration](#configuration) + - [Execution](#execution) + - [Execution payload](#execution-payload) + - [Modified `process_execution_payload`](#modified-process_execution_payload) +- [Testing](#testing) + + + + +## Introduction + +*Note:* This specification is built upon [Electra](../electra/beacon-chain.md) and is under active development. + +## Configuration + +### Execution + +| Name | Value | Description | +| - | - | - | +| `MAX_BLOBS_PER_BLOCK_EIP7594` | `uint64(8)` | *[New in EIP7494]* maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` | + + +#### Execution payload + +##### Modified `process_execution_payload` + +```python +def process_execution_payload(state: BeaconState, body: BeaconBlockBody, execution_engine: ExecutionEngine) -> None: + payload = body.execution_payload + + # Verify consistency of the parent hash with respect to the previous execution payload header + assert payload.parent_hash == state.latest_execution_payload_header.block_hash + # Verify prev_randao + assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state)) + # Verify timestamp + assert payload.timestamp == compute_timestamp_at_slot(state, state.slot) + # Verify commitments are under limit + assert len(body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK_EIP7594 # [Modified in EIP7594] + # Verify the execution payload is valid + versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments] + assert execution_engine.verify_and_notify_new_payload( + NewPayloadRequest( + execution_payload=payload, + versioned_hashes=versioned_hashes, + parent_beacon_block_root=state.latest_block_header.parent_root, + execution_requests=body.execution_requests, + ) + ) + # Cache execution payload header + state.latest_execution_payload_header = ExecutionPayloadHeader( + parent_hash=payload.parent_hash, + fee_recipient=payload.fee_recipient, + state_root=payload.state_root, + receipts_root=payload.receipts_root, + logs_bloom=payload.logs_bloom, + prev_randao=payload.prev_randao, + block_number=payload.block_number, + gas_limit=payload.gas_limit, + gas_used=payload.gas_used, + timestamp=payload.timestamp, + extra_data=payload.extra_data, + base_fee_per_gas=payload.base_fee_per_gas, + block_hash=payload.block_hash, + transactions_root=hash_tree_root(payload.transactions), + withdrawals_root=hash_tree_root(payload.withdrawals), + blob_gas_used=payload.blob_gas_used, + excess_blob_gas=payload.excess_blob_gas, + ) +``` + +## Testing + +*Note*: The function `initialize_beacon_state_from_eth1` is modified for pure EIP7594 testing only. + +```python +def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32, + eth1_timestamp: uint64, + deposits: Sequence[Deposit], + execution_payload_header: ExecutionPayloadHeader=ExecutionPayloadHeader() + ) -> BeaconState: + fork = Fork( + previous_version=EIP7594_FORK_VERSION, # [Modified in EIP7594] for testing only + current_version=EIP7594_FORK_VERSION, # [Modified in EIP7594] + epoch=GENESIS_EPOCH, + ) + state = BeaconState( + genesis_time=eth1_timestamp + GENESIS_DELAY, + fork=fork, + eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=uint64(len(deposits))), + latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), + randao_mixes=[eth1_block_hash] * EPOCHS_PER_HISTORICAL_VECTOR, # Seed RANDAO with Eth1 entropy + deposit_requests_start_index=UNSET_DEPOSIT_REQUESTS_START_INDEX, + ) + + # Process deposits + leaves = list(map(lambda deposit: deposit.data, deposits)) + for index, deposit in enumerate(deposits): + deposit_data_list = List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:index + 1]) + state.eth1_data.deposit_root = hash_tree_root(deposit_data_list) + process_deposit(state, deposit) + + # Process deposit balance updates + validator_pubkeys = [v.pubkey for v in state.validators] + for deposit in state.pending_deposits: + validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey)) + increase_balance(state, validator_index, deposit.amount) + state.pending_deposits = [] + + # Process activations + for index, validator in enumerate(state.validators): + balance = state.balances[index] + validator.effective_balance = min( + balance - balance % EFFECTIVE_BALANCE_INCREMENT, get_max_effective_balance(validator)) + if validator.effective_balance >= MIN_ACTIVATION_BALANCE: + validator.activation_eligibility_epoch = GENESIS_EPOCH + validator.activation_epoch = GENESIS_EPOCH + + # Set genesis validators root for domain separation and chain versioning + state.genesis_validators_root = hash_tree_root(state.validators) + + # Fill in sync committees + # Note: A duplicate committee is assigned for the current and next committee at genesis + state.current_sync_committee = get_next_sync_committee(state) + state.next_sync_committee = get_next_sync_committee(state) + + # Initialize the execution payload header + state.latest_execution_payload_header = execution_payload_header + + return state +``` diff --git a/specs/_features/eip7594/p2p-interface.md b/specs/_features/eip7594/p2p-interface.md index c989711807..8fa1d2b82f 100644 --- a/specs/_features/eip7594/p2p-interface.md +++ b/specs/_features/eip7594/p2p-interface.md @@ -21,11 +21,15 @@ - [MetaData](#metadata) - [The gossip domain: gossipsub](#the-gossip-domain-gossipsub) - [Topics and messages](#topics-and-messages) + - [Global topics](#global-topics) + - [`beacon_block`](#beacon_block) - [Blob subnets](#blob-subnets) - [Deprecated `blob_sidecar_{subnet_id}`](#deprecated-blob_sidecar_subnet_id) - [`data_column_sidecar_{subnet_id}`](#data_column_sidecar_subnet_id) - [The Req/Resp domain](#the-reqresp-domain) - [Messages](#messages) + - [BlobSidecarsByRoot v2](#blobsidecarsbyroot-v2) + - [BlobSidecarsByRange v2](#blobsidecarsbyrange-v2) - [DataColumnSidecarsByRoot v1](#datacolumnsidecarsbyroot-v1) - [DataColumnSidecarsByRange v1](#datacolumnsidecarsbyrange-v1) - [GetMetaData v3](#getmetadata-v3) @@ -52,6 +56,8 @@ |------------------------------------------------|------------------------------------------------|---------------------------------------------------------------------------| | `MAX_REQUEST_DATA_COLUMN_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS` | Maximum number of data column sidecars in a single request | | `MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve data column sidecars | +| `MAX_REQUEST_BLOB_SIDECARS_EIP7594` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_EIP7594` | Maximum number of blob sidecars in a single request | +| `BLOB_SIDECAR_SUBNET_COUNT_EIP7594` | `2**3` (= 8) | The number of blob sidecar subnets used in the gossipsub protocol. | ### Containers @@ -154,6 +160,16 @@ Some gossip meshes are upgraded in the EIP-7594 fork to support upgraded types. #### Topics and messages + +##### Global topics + +###### `beacon_block` + +*Updated validation* + +- _[REJECT]_ The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer -- + i.e. validate that `len(body.signed_beacon_block.message.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK_EIP7594` + ##### Blob subnets ###### Deprecated `blob_sidecar_{subnet_id}` @@ -189,6 +205,74 @@ The following validations MUST pass before forwarding the `sidecar: DataColumnSi #### Messages +##### BlobSidecarsByRoot v2 + +**Protocol ID:** `/eth2/beacon_chain/req/blob_sidecars_by_root/2/` + +*[Updated in EIP7594]* + +The `` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`: + +[1]: # (eth2spec: skip) + +| `fork_version` | Chunk SSZ type | +|--------------------------|-------------------------------| +| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | + +Request Content: + +``` +( + List[BlobIdentifier, MAX_REQUEST_BLOB_SIDECARS_EIP7594] +) +``` + +Response Content: + +``` +( + List[BlobSidecar, MAX_REQUEST_BLOB_SIDECARS_EIP7594] +) +``` + +*Updated validation* + +No more than `MAX_REQUEST_BLOB_SIDECARS_EIP7594` may be requested at a time. + + +##### BlobSidecarsByRange v2 + +**Protocol ID:** `/eth2/beacon_chain/req/blob_sidecars_by_range/2/` + +*[Updated in EIP7594]* + +The `` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`: + +[1]: # (eth2spec: skip) + +| `fork_version` | Chunk SSZ type | +|--------------------------|-------------------------------| +| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | + +Request Content: +``` +( + start_slot: Slot + count: uint64 +) +``` + +Response Content: +``` +( + List[BlobSidecar, MAX_REQUEST_BLOB_SIDECARS_EIP7594] +) +``` + +*Updated validation* + +Clients MUST respond with at least the blob sidecars of the first blob-carrying block that exists in the range, if they have it, and no more than `MAX_REQUEST_BLOB_SIDECARS_EIP7594` sidecars. + ##### DataColumnSidecarsByRoot v1 **Protocol ID:** `/eth2/beacon_chain/req/data_column_sidecars_by_root/1/` diff --git a/specs/deneb/beacon-chain.md b/specs/deneb/beacon-chain.md index 0f6a8fc076..3404b11713 100644 --- a/specs/deneb/beacon-chain.md +++ b/specs/deneb/beacon-chain.md @@ -77,7 +77,7 @@ Deneb is a consensus-layer upgrade containing a number of features. Including: | Name | Value | Description | | - | - | - | -| `MAX_BLOB_COMMITMENTS_PER_BLOCK` | `uint64(2**12)` (= 4096) | *[New in Deneb:EIP4844]* hardfork independent fixed theoretical limit same as `LIMIT_BLOBS_PER_TX` (see EIP 4844) | +| `MAX_BLOB_COMMITMENTS_PER_BLOCK` | `uint64(2**12)` (= 4096) | *[New in Deneb:EIP4844]* hardfork independent fixed theoretical limit same as `TARGET_BLOB_GAS_PER_BLOCK` (see EIP 4844) | ## Configuration From f67e6cc359feb634b8a4d303891e774e15009e03 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 13 Nov 2024 14:23:23 +0700 Subject: [PATCH 2/5] update tests --- .../test_process_execution_payload.py | 3 ++- .../eth2spec/test/deneb/sanity/test_blocks.py | 11 ++++++----- .../eip7594/unittests/test_config_invariants.py | 13 +++++++++++++ tests/core/pyspec/eth2spec/test/helpers/blob.py | 11 +++++++++++ .../pyspec/eth2spec/test/helpers/fork_choice.py | 2 +- tests/core/pyspec/eth2spec/test/helpers/forks.py | 6 +++++- .../eth2spec/test/utils/randomized_block_tests.py | 1 + tests/formats/fork_choice/README.md | 2 +- 8 files changed, 40 insertions(+), 9 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/deneb/block_processing/test_process_execution_payload.py b/tests/core/pyspec/eth2spec/test/deneb/block_processing/test_process_execution_payload.py index d0c4a6f22a..e8ac314e10 100644 --- a/tests/core/pyspec/eth2spec/test/deneb/block_processing/test_process_execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/deneb/block_processing/test_process_execution_payload.py @@ -12,6 +12,7 @@ ) from eth2spec.test.helpers.blob import ( get_sample_blob_tx, + get_max_blob_count, ) @@ -254,7 +255,7 @@ def test_invalid_correct_input__execution_invalid(spec, state): def test_invalid_exceed_max_blobs_per_block(spec, state): execution_payload = build_empty_execution_payload(spec, state) - opaque_tx, _, blob_kzg_commitments, _ = get_sample_blob_tx(spec, blob_count=spec.config.MAX_BLOBS_PER_BLOCK + 1) + opaque_tx, _, blob_kzg_commitments, _ = get_sample_blob_tx(spec, blob_count=get_max_blob_count(spec) + 1) execution_payload.transactions = [opaque_tx] execution_payload.block_hash = compute_el_block_hash(spec, execution_payload, state) diff --git a/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py index b019175369..19c0fcd0c5 100644 --- a/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py @@ -16,6 +16,7 @@ ) from eth2spec.test.helpers.blob import ( get_sample_blob_tx, + get_max_blob_count, ) @@ -72,31 +73,31 @@ def test_one_blob_two_txs(spec, state): @with_deneb_and_later @spec_state_test def test_one_blob_max_txs(spec, state): - yield from run_block_with_blobs(spec, state, blob_count=1, tx_count=spec.MAX_BLOBS_PER_BLOCK) + yield from run_block_with_blobs(spec, state, blob_count=1, tx_count=get_max_blob_count(spec)) @with_deneb_and_later @spec_state_test def test_invalid_one_blob_max_plus_one_txs(spec, state): - yield from run_block_with_blobs(spec, state, blob_count=1, tx_count=spec.MAX_BLOBS_PER_BLOCK + 1, valid=False) + yield from run_block_with_blobs(spec, state, blob_count=1, tx_count=get_max_blob_count(spec) + 1, valid=False) @with_deneb_and_later @spec_state_test def test_max_blobs_per_block(spec, state): - yield from run_block_with_blobs(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK) + yield from run_block_with_blobs(spec, state, blob_count=get_max_blob_count(spec)) @with_deneb_and_later @spec_state_test def test_invalid_max_blobs_per_block_two_txs(spec, state): - yield from run_block_with_blobs(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK, tx_count=2, valid=False) + yield from run_block_with_blobs(spec, state, blob_count=get_max_blob_count(spec), tx_count=2, valid=False) @with_deneb_and_later @spec_state_test def test_invalid_exceed_max_blobs_per_block(spec, state): - yield from run_block_with_blobs(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK + 1, valid=False) + yield from run_block_with_blobs(spec, state, blob_count=get_max_blob_count(spec) + 1, valid=False) @with_deneb_and_later diff --git a/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py b/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py index fc54cc3088..2c291890d4 100644 --- a/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py +++ b/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py @@ -25,3 +25,16 @@ def test_invariants(spec): @single_phase def test_polynomical_commitments_sampling(spec): assert spec.FIELD_ELEMENTS_PER_EXT_BLOB == 2 * spec.FIELD_ELEMENTS_PER_BLOB + + +@with_eip7594_and_later +@spec_test +@single_phase +def test_networking(spec): + assert spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 < spec.MAX_BLOB_COMMITMENTS_PER_BLOCK + assert ( + spec.config.MAX_REQUEST_BLOB_SIDECARS_EIP7594 == + spec.config.MAX_REQUEST_BLOCKS_DENEB * spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 + ) + # Start with the same size, but `BLOB_SIDECAR_SUBNET_COUNT` could potentially increase later. + assert spec.config.BLOB_SIDECAR_SUBNET_COUNT_EIP7594 == spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 diff --git a/tests/core/pyspec/eth2spec/test/helpers/blob.py b/tests/core/pyspec/eth2spec/test/helpers/blob.py index fb2354a501..a31f032dcd 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/blob.py +++ b/tests/core/pyspec/eth2spec/test/helpers/blob.py @@ -2,6 +2,10 @@ from rlp import encode, Serializable from rlp.sedes import Binary, CountableList, List as RLPList, big_endian_int, binary +from eth2spec.test.helpers.forks import ( + is_post_eip7594, +) + class Eip4844RlpTransaction(Serializable): fields = ( @@ -99,3 +103,10 @@ def get_sample_blob_tx(spec, blob_count=1, rng=random.Random(5566), is_valid_blo ) opaque_tx = bytes([0x03]) + encode(signed_blob_tx) return opaque_tx, blobs, blob_kzg_commitments, blob_kzg_proofs + + +def get_max_blob_count(spec): + if is_post_eip7594: + return spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 + else: + return spec.config.MAX_BLOBS_PER_BLOCK diff --git a/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py b/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py index 8598870fb6..43555c268d 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py +++ b/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py @@ -178,7 +178,7 @@ def add_block(spec, # Check blob_data if blob_data is not None: - blobs = spec.List[spec.Blob, spec.config.MAX_BLOBS_PER_BLOCK](blob_data.blobs) + blobs = spec.List[spec.Blob, spec.config.MAX_BLOB_COMMITMENTS_PER_BLOCK](blob_data.blobs) blobs_root = blobs.hash_tree_root() yield get_blobs_file_name(blobs_root=blobs_root), blobs diff --git a/tests/core/pyspec/eth2spec/test/helpers/forks.py b/tests/core/pyspec/eth2spec/test/helpers/forks.py index 288ad0d9e9..e261e3a754 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/forks.py +++ b/tests/core/pyspec/eth2spec/test/helpers/forks.py @@ -1,6 +1,6 @@ from .constants import ( PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, - ELECTRA, WHISK, EIP7732, + ELECTRA, WHISK, EIP7732, EIP7594, PREVIOUS_FORK_OF, ) @@ -45,6 +45,10 @@ def is_post_whisk(spec): return is_post_fork(spec.fork, WHISK) +def is_post_eip7594(spec): + return is_post_fork(spec.fork, EIP7594) + + def is_post_eip7732(spec): return is_post_fork(spec.fork, EIP7732) diff --git a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py index 6e6cdd7683..93bb3b204c 100644 --- a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py +++ b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py @@ -250,6 +250,7 @@ def random_block_capella(spec, state, signed_blocks, scenario_state, rng=Random( def random_block_deneb(spec, state, signed_blocks, scenario_state, rng=Random(3456)): block = random_block_capella(spec, state, signed_blocks, scenario_state, rng=rng) # TODO: more commitments. blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] + # TODO: add MAX_BLOBS_PER_BLOCK_EIP7594 at fulu opaque_tx, _, blob_kzg_commitments, _ = get_sample_blob_tx( spec, blob_count=rng.randint(0, spec.config.MAX_BLOBS_PER_BLOCK), rng=rng) block.body.execution_payload.transactions.append(opaque_tx) diff --git a/tests/formats/fork_choice/README.md b/tests/formats/fork_choice/README.md index 1258a66c06..258dfe433d 100644 --- a/tests/formats/fork_choice/README.md +++ b/tests/formats/fork_choice/README.md @@ -86,7 +86,7 @@ The parameter that is required for executing `on_block(store, block)`. block: string -- the name of the `block_<32-byte-root>.ssz_snappy` file. To execute `on_block(store, block)` with the given attestation. blobs: string -- optional, the name of the `blobs_<32-byte-root>.ssz_snappy` file. - The blobs file content is a `List[Blob, MAX_BLOBS_PER_BLOCK]` SSZ object. + The blobs file content is a `List[Blob, MAX_BLOB_COMMITMENTS_PER_BLOCK]` SSZ object. proofs: array of byte48 hex string -- optional, the proofs of blob commitments. valid: bool -- optional, default to `true`. If it's `false`, this execution step is expected to be invalid. From ac53675d24915ffe1c4a81c8caf025d2dab5ed25 Mon Sep 17 00:00:00 2001 From: Justin Traglia Date: Tue, 19 Nov 2024 14:26:08 -0600 Subject: [PATCH 3/5] Fix some minor nits --- specs/_features/eip7594/beacon-chain.md | 3 +- specs/_features/eip7594/p2p-interface.md | 30 ++++++++++--------- .../unittests/test_config_invariants.py | 2 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/specs/_features/eip7594/beacon-chain.md b/specs/_features/eip7594/beacon-chain.md index bf980b840d..28031178e1 100644 --- a/specs/_features/eip7594/beacon-chain.md +++ b/specs/_features/eip7594/beacon-chain.md @@ -28,8 +28,7 @@ | Name | Value | Description | | - | - | - | -| `MAX_BLOBS_PER_BLOCK_EIP7594` | `uint64(8)` | *[New in EIP7494]* maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` | - +| `MAX_BLOBS_PER_BLOCK_EIP7594` | `uint64(8)` | *[New in EIP7594]* Maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` | #### Execution payload diff --git a/specs/_features/eip7594/p2p-interface.md b/specs/_features/eip7594/p2p-interface.md index 8fa1d2b82f..de2d7e1f0b 100644 --- a/specs/_features/eip7594/p2p-interface.md +++ b/specs/_features/eip7594/p2p-interface.md @@ -52,12 +52,12 @@ *[New in EIP7594]* -| Name | Value | Description | -|------------------------------------------------|------------------------------------------------|---------------------------------------------------------------------------| -| `MAX_REQUEST_DATA_COLUMN_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS` | Maximum number of data column sidecars in a single request | -| `MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve data column sidecars | -| `MAX_REQUEST_BLOB_SIDECARS_EIP7594` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_EIP7594` | Maximum number of blob sidecars in a single request | -| `BLOB_SIDECAR_SUBNET_COUNT_EIP7594` | `2**3` (= 8) | The number of blob sidecar subnets used in the gossipsub protocol. | +| Name | Value | Description | +|------------------------------------------------|----------------------------------------------------------|---------------------------------------------------------------------------| +| `MAX_REQUEST_DATA_COLUMN_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS` | Maximum number of data column sidecars in a single request | +| `MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve data column sidecars | +| `MAX_REQUEST_BLOB_SIDECARS_EIP7594` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_EIP7594` | Maximum number of blob sidecars in a single request | +| `BLOB_SIDECAR_SUBNET_COUNT_EIP7594` | `2**3` (= 8) | The number of blob sidecar subnets used in the gossipsub protocol | ### Containers @@ -160,7 +160,6 @@ Some gossip meshes are upgraded in the EIP-7594 fork to support upgraded types. #### Topics and messages - ##### Global topics ###### `beacon_block` @@ -215,9 +214,9 @@ The `` field is calculated as `context = compute_fork_digest(fork [1]: # (eth2spec: skip) -| `fork_version` | Chunk SSZ type | -|--------------------------|-------------------------------| -| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | +| `fork_version` | Chunk SSZ type | +|------------------------|-----------------------| +| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | Request Content: @@ -239,7 +238,6 @@ Response Content: No more than `MAX_REQUEST_BLOB_SIDECARS_EIP7594` may be requested at a time. - ##### BlobSidecarsByRange v2 **Protocol ID:** `/eth2/beacon_chain/req/blob_sidecars_by_range/2/` @@ -250,11 +248,12 @@ The `` field is calculated as `context = compute_fork_digest(fork [1]: # (eth2spec: skip) -| `fork_version` | Chunk SSZ type | -|--------------------------|-------------------------------| -| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | +| `fork_version` | Chunk SSZ type | +|------------------------|-----------------------| +| `EIP7594_FORK_VERSION` | `eip7594.BlobSidecar` | Request Content: + ``` ( start_slot: Slot @@ -263,6 +262,7 @@ Request Content: ``` Response Content: + ``` ( List[BlobSidecar, MAX_REQUEST_BLOB_SIDECARS_EIP7594] @@ -336,6 +336,7 @@ The `` field is calculated as `context = compute_fork_digest(fork | `EIP7594_FORK_VERSION` | `eip7594.DataColumnSidecar` | Request Content: + ``` ( start_slot: Slot @@ -345,6 +346,7 @@ Request Content: ``` Response Content: + ``` ( List[DataColumnSidecar, MAX_REQUEST_DATA_COLUMN_SIDECARS] diff --git a/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py b/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py index 2c291890d4..8d14f4ae1c 100644 --- a/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py +++ b/tests/core/pyspec/eth2spec/test/eip7594/unittests/test_config_invariants.py @@ -31,7 +31,7 @@ def test_polynomical_commitments_sampling(spec): @spec_test @single_phase def test_networking(spec): - assert spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 < spec.MAX_BLOB_COMMITMENTS_PER_BLOCK + assert spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 <= spec.MAX_BLOB_COMMITMENTS_PER_BLOCK assert ( spec.config.MAX_REQUEST_BLOB_SIDECARS_EIP7594 == spec.config.MAX_REQUEST_BLOCKS_DENEB * spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 From 7b0b7df0156edeb31b465a9a31fcfdbbc272c7b6 Mon Sep 17 00:00:00 2001 From: Justin Traglia Date: Tue, 19 Nov 2024 14:33:16 -0600 Subject: [PATCH 4/5] Fix bug --- tests/core/pyspec/eth2spec/test/helpers/blob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/blob.py b/tests/core/pyspec/eth2spec/test/helpers/blob.py index a31f032dcd..c65414b02b 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/blob.py +++ b/tests/core/pyspec/eth2spec/test/helpers/blob.py @@ -106,7 +106,7 @@ def get_sample_blob_tx(spec, blob_count=1, rng=random.Random(5566), is_valid_blo def get_max_blob_count(spec): - if is_post_eip7594: + if is_post_eip7594(spec): return spec.config.MAX_BLOBS_PER_BLOCK_EIP7594 else: return spec.config.MAX_BLOBS_PER_BLOCK From 5753be7e78cfc2e62ea988e155c5a7c74258fde9 Mon Sep 17 00:00:00 2001 From: Justin Traglia Date: Tue, 19 Nov 2024 14:53:38 -0600 Subject: [PATCH 5/5] Fix blobs cast --- tests/core/pyspec/eth2spec/test/helpers/fork_choice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py b/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py index 43555c268d..33e8535502 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py +++ b/tests/core/pyspec/eth2spec/test/helpers/fork_choice.py @@ -178,7 +178,7 @@ def add_block(spec, # Check blob_data if blob_data is not None: - blobs = spec.List[spec.Blob, spec.config.MAX_BLOB_COMMITMENTS_PER_BLOCK](blob_data.blobs) + blobs = spec.List[spec.Blob, spec.MAX_BLOB_COMMITMENTS_PER_BLOCK](blob_data.blobs) blobs_root = blobs.hash_tree_root() yield get_blobs_file_name(blobs_root=blobs_root), blobs