Merge pull request #3338 from g11tech/update-max-blobs-limit-mainnet

Update block's `blob_kzg_commitments` size limit to MAX_BLOB_COMMITMENTS_PER_BLOCK (4096)
This commit is contained in:
Hsiao-Wei Wang
2023-05-24 16:50:13 +08:00
committed by GitHub
8 changed files with 62 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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 |
@@ -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
@@ -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`
@@ -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)

View File

@@ -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`.

View File

@@ -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)

View File

@@ -16,7 +16,7 @@ from eth2spec.test.helpers.sharding import (
)
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)
@@ -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
@@ -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)

View File

@@ -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