diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 92be2ce25..3c04947d4 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -73,10 +73,15 @@ - [New `process_pending_balance_deposits`](#new-process_pending_balance_deposits) - [New `process_pending_consolidations`](#new-process_pending_consolidations) - [Modified `process_effective_balance_updates`](#modified-process_effective_balance_updates) + - [Execution engine](#execution-engine) + - [Request data](#request-data) + - [Modified `NewPayloadRequest`](#modified-newpayloadrequest) - [Block processing](#block-processing) - [Withdrawals](#withdrawals) - [Modified `get_expected_withdrawals`](#modified-get_expected_withdrawals) - [Modified `process_withdrawals`](#modified-process_withdrawals) + - [Execution payload](#execution-payload) + - [Modified `process_execution_payload`](#modified-process_execution_payload) - [Operations](#operations) - [Modified `process_operations`](#modified-process_operations) - [Attestations](#attestations) @@ -894,6 +899,21 @@ def process_effective_balance_updates(state: BeaconState) -> None: validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, EFFECTIVE_BALANCE_LIMIT) ``` +### Execution engine + +#### Request data + +##### Modified `NewPayloadRequest` + +```python +@dataclass +class NewPayloadRequest(object): + execution_payload: ExecutionPayload + execution_requests: ExecutionLayerRequests + versioned_hashes: Sequence[VersionedHash] + parent_beacon_block_root: Root +``` + ### Block processing ```python @@ -1000,6 +1020,57 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None: next_validator_index = ValidatorIndex(next_index % len(state.validators)) state.next_withdrawal_validator_index = next_validator_index ``` + +#### Execution payload + +##### Modified `process_execution_payload` + +*Note*: The function `process_execution_payload` is modified to pass `execution_requests` into `execution_engine.verify_and_notify_new_payload` (via the updated `NewPayloadRequest`). + +```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 + # 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, + execution_requests=body.execution_requests, # [New in Electra] + versioned_hashes=versioned_hashes, + parent_beacon_block_root=state.latest_block_header.parent_root, + ) + ) + # 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 + ) +``` + #### Operations ##### Modified `process_operations`