diff --git a/specs/eip4844/beacon-chain.md b/specs/eip4844/beacon-chain.md index 4cf953593..877c3332a 100644 --- a/specs/eip4844/beacon-chain.md +++ b/specs/eip4844/beacon-chain.md @@ -15,6 +15,7 @@ - [Domain types](#domain-types) - [Preset](#preset) - [Execution](#execution) + - [Test Parameters](#test-parameters) - [Configuration](#configuration) - [Containers](#containers) - [Extended containers](#extended-containers) @@ -27,9 +28,11 @@ - [`tx_peek_blob_versioned_hashes`](#tx_peek_blob_versioned_hashes) - [`verify_kzg_commitments_against_transactions`](#verify_kzg_commitments_against_transactions) - [Beacon chain state transition function](#beacon-chain-state-transition-function) + - [Epoch processing](#epoch-processing) - [Block processing](#block-processing) - [Execution payload](#execution-payload) - [`process_execution_payload`](#process_execution_payload) + - [Modified `process_operations`](#modified-process_operations) - [Blob KZG commitments](#blob-kzg-commitments) - [Testing](#testing) @@ -38,7 +41,7 @@ ## Introduction -This upgrade adds blobs to the beacon chain as part of EIP-4844. +This upgrade adds blobs to the beacon chain as part of EIP-4844. This is an extension of the Capella upgrade. We introduce a new feature flag, `ENABLE_WITHDRAWALS`, to disable Capella-specific updates to the state transition function. This is done to minimize Capella specific issues that may arise during testing. `ENABLE_WITHDRAWALS` will be removed in the final upgrade specification. ## Custom types @@ -72,6 +75,10 @@ This upgrade adds blobs to the beacon chain as part of EIP-4844. | - | - | | `MAX_BLOBS_PER_BLOCK` | `uint64(2**4)` (= 16) | +### Test Parameters +| Name | Value | +| `ENABLE_WITHDRAWALS` | `uint64(0)` | + ## Configuration @@ -97,6 +104,7 @@ class BeaconBlockBody(Container): sync_aggregate: SyncAggregate # Execution execution_payload: ExecutionPayload + bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES] blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in EIP-4844] ``` @@ -121,6 +129,7 @@ class ExecutionPayload(Container): # Extra payload fields block_hash: Hash32 # Hash of execution block transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD] + withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] ``` #### `ExecutionPayloadHeader` @@ -144,6 +153,7 @@ class ExecutionPayloadHeader(Container): # Extra payload fields block_hash: Hash32 # Hash of execution block transactions_root: Root + withdrawals_root: Root ``` ## Helper functions @@ -192,13 +202,37 @@ def verify_kzg_commitments_against_transactions(transactions: Sequence[Transacti ## Beacon chain state transition function +### Epoch processing + +```python +def process_epoch(state: BeaconState) -> None: + process_justification_and_finalization(state) + process_inactivity_updates(state) + process_rewards_and_penalties(state) + process_registry_updates(state) + process_slashings(state) + process_eth1_data_reset(state) + process_effective_balance_updates(state) + process_slashings_reset(state) + process_randao_mixes_reset(state) + process_historical_roots_update(state) + process_participation_flag_updates(state) + process_sync_committee_updates(state) + if ENABLE_WITHDRAWALS: + process_full_withdrawals(state) + process_partial_withdrawals(state) +``` + + ### Block processing ```python def process_block(state: BeaconState, block: BeaconBlock) -> None: process_block_header(state, block) if is_execution_enabled(state, block.body): - process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) + if ENABLE_WITHDRAWALS: # [New in EIP-4844] + process_withdrawals(state, block.body.execution_payload) + process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) # [Modified in EIP-4844] process_randao(state, block.body) process_eth1_data(state, block.body) process_operations(state, block.body) @@ -221,6 +255,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe assert payload.timestamp == compute_timestamp_at_slot(state, state.slot) # Verify the execution payload is valid assert execution_engine.notify_new_payload(payload) + # Cache execution payload header state.latest_execution_payload_header = ExecutionPayloadHeader( parent_hash=payload.parent_hash, @@ -238,9 +273,32 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe excess_blobs=payload.excess_blobs, # [New in EIP-4844] block_hash=payload.block_hash, transactions_root=hash_tree_root(payload.transactions), - ) + withdrawals_root=hash_tree_root(payload.withdrawals) if ENABLE_WITHDRAWALS else Bytes32(), # [New in EIP-4844] ``` +#### Modified `process_operations` + +*Note*: The function `process_operations` is modified to feature flag Withdrawals. + +```python +def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: + # Verify that outstanding deposits are processed up to the maximum number of deposits + assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index) + + def for_ops(operations: Sequence[Any], fn: Callable[[BeaconState, Any], None]) -> None: + for operation in operations: + fn(state, operation) + + for_ops(body.proposer_slashings, process_proposer_slashing) + for_ops(body.attester_slashings, process_attester_slashing) + for_ops(body.attestations, process_attestation) + for_ops(body.deposits, process_deposit) + for_ops(body.voluntary_exits, process_voluntary_exit) + if ENABLE_WITHDRAWALS: # [New in EIP-4844] + for_ops(body.bls_to_execution_changes, process_bls_to_execution_change) +``` + + #### Blob KZG commitments ```python diff --git a/specs/eip4844/fork.md b/specs/eip4844/fork.md index eaabba916..bce6ffe70 100644 --- a/specs/eip4844/fork.md +++ b/specs/eip4844/fork.md @@ -44,6 +44,8 @@ def compute_fork_version(epoch: Epoch) -> Version: """ if epoch >= EIP4844_FORK_EPOCH: return EIP4844_FORK_VERSION + if epoch >= CAPELLA_FORK_EPOCH: + return CAPELLA_FORK_VERSION if epoch >= BELLATRIX_FORK_EPOCH: return BELLATRIX_FORK_VERSION if epoch >= ALTAIR_FORK_EPOCH: @@ -62,12 +64,11 @@ Note that for the pure EIP-4844 networks, we don't apply `upgrade_to_eip4844` si ### Upgrading the state -Since the `eip4844.BeaconState` format is equal to the `bellatrix.BeaconState` format, we only have to update `BeaconState.fork`. +Since the `eip4844.BeaconState` format is equal to the `Capella.BeaconState` format, we only have to update `BeaconState.fork`. ```python -def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState: - # TODO: if Capella gets scheduled, add sync it with Capella.BeaconState - epoch = bellatrix.get_current_epoch(pre) +def upgrade_to_eip4844(pre: Capella.BeaconState) -> BeaconState: + epoch = capella.get_current_epoch(pre) post = BeaconState( # Versioning genesis_time=pre.genesis_time, @@ -109,6 +110,10 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState: next_sync_committee=pre.next_sync_committee, # Execution-layer latest_execution_payload_header=pre.latest_execution_payload_header, + # Withdrawals + withdrawal_queue=[], + next_withdrawal_index=WithdrawalIndex(0), + next_partial_withdrawal_validator_index=ValidatorIndex(0), ) return post diff --git a/specs/eip4844/p2p-interface.md b/specs/eip4844/p2p-interface.md index eab8815a4..60ccb0739 100644 --- a/specs/eip4844/p2p-interface.md +++ b/specs/eip4844/p2p-interface.md @@ -67,7 +67,7 @@ Some gossip meshes are upgraded in the fork of EIP4844 to support upgraded types Topics follow the same specification as in prior upgrades. All topics remain stable except the beacon block topic which is updated with the modified type. -The specification around the creation, validation, and dissemination of messages has not changed from the Bellatrix document unless explicitly noted here. +The specification around the creation, validation, and dissemination of messages has not changed from the Capella document unless explicitly noted here. The derivation of the `message-id` remains stable. diff --git a/specs/eip4844/validator.md b/specs/eip4844/validator.md index e1bcf9564..c998aeb6e 100644 --- a/specs/eip4844/validator.md +++ b/specs/eip4844/validator.md @@ -15,6 +15,9 @@ - [`BlobsAndCommitments`](#blobsandcommitments) - [`PolynomialAndCommitment`](#polynomialandcommitment) - [Helpers](#helpers) +- [Protocols](#protocols) + - [`ExecutionEngine`](#executionengine) + - [`get_payload`](#get_payload) - [`is_data_available`](#is_data_available) - [`hash_to_bls_field`](#hash_to_bls_field) - [`compute_powers`](#compute_powers) @@ -27,6 +30,7 @@ - [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody) - [Blob KZG commitments](#blob-kzg-commitments) - [Beacon Block publishing time](#beacon-block-publishing-time) + - [ExecutionPayload](#executionpayload) @@ -37,7 +41,7 @@ This document represents the changes to be made in the code of an "honest valida ## Prerequisites -This document is an extension of the [Bellatrix -- Honest Validator](../bellatrix/validator.md) guide. +This document is an extension of the [Capella -- Honest Validator](../capella/validator.md) guide. All behaviors and definitions defined in this document, and documents it extends, carry over unless explicitly noted or overridden. All terminology, constants, functions, and protocol mechanics defined in the updated [Beacon Chain doc of EIP4844](./beacon-chain.md) are requisite for this document and used throughout. @@ -70,6 +74,14 @@ class PolynomialAndCommitment(Container): ## Helpers +## Protocols + +### `ExecutionEngine` + +#### `get_payload` + +`get_payload` returns the upgraded EIP-4844 `ExecutionPayload` type. + ### `is_data_available` The implementation of `is_data_available` is meant to change with later sharding upgrades. @@ -200,7 +212,7 @@ Namely, the blob handling and the addition of `BlobsSidecar`. ##### Blob KZG commitments -1. After retrieving the execution payload from the execution engine as specified in Bellatrix, +1. After retrieving the execution payload from the execution engine as specified in Capella, use the `payload_id` to retrieve `blobs` and `blob_kzg_commitments` via `get_blobs_and_kzg_commitments(payload_id)`. 2. Validate `blobs` and `blob_kzg_commitments`: @@ -252,3 +264,46 @@ The validator MUST hold on to blobs for `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` 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. + +##### ExecutionPayload + +`ExecutionPayload`s are constructed as they were in Capella, except that we allow withdrawals to be disabled for testing. + +```python +def prepare_execution_payload(state: BeaconState, + pow_chain: Dict[Hash32, PowBlock], + safe_block_hash: Hash32, + finalized_block_hash: Hash32, + suggested_fee_recipient: ExecutionAddress, + execution_engine: ExecutionEngine) -> Optional[PayloadId]: + if not is_merge_transition_complete(state): + is_terminal_block_hash_set = TERMINAL_BLOCK_HASH != Hash32() + is_activation_epoch_reached = get_current_epoch(state) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH + if is_terminal_block_hash_set and not is_activation_epoch_reached: + # Terminal block hash is set but activation epoch is not yet reached, no prepare payload call is needed + return None + + terminal_pow_block = get_terminal_pow_block(pow_chain) + if terminal_pow_block is None: + # Pre-merge, no prepare payload call is needed + return None + # Signify merge via producing on top of the terminal PoW block + parent_hash = terminal_pow_block.block_hash + else: + # Post-merge, normal payload + parent_hash = state.latest_execution_payload_header.block_hash + + # Set the forkchoice head and initiate the payload build process + payload_attributes = PayloadAttributes( + timestamp=compute_timestamp_at_slot(state, state.slot), + prev_randao=get_randao_mix(state, get_current_epoch(state)), + suggested_fee_recipient=suggested_fee_recipient, + withdrawals=get_expected_withdrawals(state) if ENABLE_WITHDRAWALS else None, # [New in EIP-4844] + ) + return execution_engine.notify_forkchoice_updated( + head_block_hash=parent_hash, + safe_block_hash=safe_block_hash, + finalized_block_hash=finalized_block_hash, + payload_attributes=payload_attributes, + ) +```