Skip to content

Commit

Permalink
Merge pull request #3338 from g11tech/update-max-blobs-limit-mainnet
Browse files Browse the repository at this point in the history
Update block's `blob_kzg_commitments` size limit to MAX_BLOB_COMMITMENTS_PER_BLOCK (4096)
  • Loading branch information
hwwhww authored May 24, 2023
2 parents 2225fd3 + e9cc8dc commit b646c60
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 7 deletions.
2 changes: 2 additions & 0 deletions presets/mainnet/deneb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
# ---------------------------------------------------------------
# `uint64(4096)`
FIELD_ELEMENTS_PER_BLOB: 4096
# `uint64(2**12)` (= 4096)
MAX_BLOB_COMMITMENTS_PER_BLOCK: 4096
# `uint64(2**2)` (= 4)
MAX_BLOBS_PER_BLOCK: 4
2 changes: 2 additions & 0 deletions presets/minimal/deneb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
# ---------------------------------------------------------------
# [customized]
FIELD_ELEMENTS_PER_BLOB: 4
# [customized]
MAX_BLOB_COMMITMENTS_PER_BLOCK: 16
# `uint64(2**2)` (= 4)
MAX_BLOBS_PER_BLOCK: 4
2 changes: 2 additions & 0 deletions specs/_features/eip6110/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi
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
# 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(
Expand Down
13 changes: 10 additions & 3 deletions specs/deneb/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

This upgrade adds blobs to the beacon chain as part of Deneb. This is an extension of the Capella upgrade.

The blob transactions are packed into the execution payload by the EL/builder with their corresponding blobs being independently transmitted and are limited by `MAX_DATA_GAS_PER_BLOCK // DATA_GAS_PER_BLOB`. However the CL limit is independently defined by `MAX_BLOBS_PER_BLOCK`.

## Custom types

| Name | SSZ equivalent | Description |
Expand Down Expand Up @@ -71,7 +73,8 @@ This upgrade adds blobs to the beacon chain as part of Deneb. This is an extensi

| Name | Value |
| - | - |
| `MAX_BLOBS_PER_BLOCK` | `uint64(2**2)` (= 4) |
| `MAX_BLOB_COMMITMENTS_PER_BLOCK` | `uint64(2**12)` (= 4096) | hardfork independent fixed theoretical limit same as `LIMIT_BLOBS_PER_TX` (see EIP 4844) |
| `MAX_BLOBS_PER_BLOCK` | `uint64(2**2)` (= 4) | Maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` |

## Configuration

Expand Down Expand Up @@ -99,7 +102,7 @@ class BeaconBlockBody(Container):
# Execution
execution_payload: ExecutionPayload # [Modified in Deneb]
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in Deneb]
blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK] # [New in Deneb]
```

#### `ExecutionPayload`
Expand Down Expand Up @@ -226,8 +229,12 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi
assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
# Verify timestamp
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)

# [New in Deneb] Verify commitments are under limit
assert len(body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK

# Verify the execution payload is valid
# [Modified in Deneb]
# [Modified in Deneb] Pass `versioned_hashes` to Engine API
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)
Expand Down
5 changes: 5 additions & 0 deletions specs/deneb/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ Deneb introduces new global topics for blob sidecars.

The *type* of the payload of this topic changes to the (modified) `SignedBeaconBlock` found in deneb.

New 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`

###### `blob_sidecar_{subnet_id}`

This topic is used to propagate signed blob sidecars, where each blob index maps to some `subnet_id`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,16 @@ def test_invalid_correct_input__execution_invalid(spec, state):

yield from run_execution_payload_processing(spec, state, execution_payload, blob_kzg_commitments,
valid=False, execution_valid=False)


@with_deneb_and_later
@spec_state_test
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_opaque_tx(spec, blob_count=spec.MAX_BLOBS_PER_BLOCK + 1)

execution_payload.transactions = [opaque_tx]
execution_payload.block_hash = compute_el_block_hash(spec, execution_payload)

yield from run_execution_payload_processing(spec, state, execution_payload, blob_kzg_commitments, valid=False)
20 changes: 16 additions & 4 deletions tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)


def run_block_with_blobs(spec, state, blob_count, excess_data_gas=1):
def run_block_with_blobs(spec, state, blob_count, excess_data_gas=1, valid=True):
yield 'pre', state

block = build_empty_block_for_next_slot(spec, state)
Expand All @@ -25,10 +25,16 @@ def run_block_with_blobs(spec, state, blob_count, excess_data_gas=1):
block.body.execution_payload.transactions = [opaque_tx]
block.body.execution_payload.excess_data_gas = excess_data_gas
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block)

print(len(block.body.blob_kzg_commitments))

if valid:
signed_block = state_transition_and_sign_block(spec, state, block)
else:
signed_block = state_transition_and_sign_block(spec, state, block, expect_fail=True)

yield 'blocks', [signed_block]
yield 'post', state
yield 'post', state if valid else None


@with_deneb_and_later
Expand All @@ -45,5 +51,11 @@ def test_one_blob(spec, state):

@with_deneb_and_later
@spec_state_test
def test_max_blobs(spec, state):
def test_max_blobs_per_block(spec, state):
yield from run_block_with_blobs(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK)


@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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from eth2spec.test.context import (
single_phase,
spec_test,
with_deneb_and_later,
)


@with_deneb_and_later
@spec_test
@single_phase
def test_length(spec):
assert spec.MAX_BLOBS_PER_BLOCK < spec.MAX_BLOB_COMMITMENTS_PER_BLOCK

0 comments on commit b646c60

Please sign in to comment.