diff --git a/pysetup/spec_builders/electra.py b/pysetup/spec_builders/electra.py index 2ab1f5ecfb..48082249b6 100644 --- a/pysetup/spec_builders/electra.py +++ b/pysetup/spec_builders/electra.py @@ -10,6 +10,7 @@ class ElectraSpecBuilder(BaseSpecBuilder): def imports(cls, preset_name: str): return f''' from eth2spec.deneb import {preset_name} as deneb +from eth2spec.utils.ssz.ssz_impl import serialize ''' @classmethod @@ -28,8 +29,8 @@ class NoopExecutionEngine(ExecutionEngine): def notify_new_payload(self: ExecutionEngine, execution_payload: ExecutionPayload, - execution_requests: ExecutionRequests, - parent_beacon_block_root: Root) -> bool: + parent_beacon_block_root: Root, + execution_requests_list: list[bytes]) -> bool: return True def notify_forkchoice_updated(self: ExecutionEngine, diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index c231e718e7..7c6d9fe1fa 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -84,6 +84,7 @@ - [Modified `get_expected_withdrawals`](#modified-get_expected_withdrawals) - [Modified `process_withdrawals`](#modified-process_withdrawals) - [Execution payload](#execution-payload) + - [New `get_execution_requests_list`](#new-get_execution_requests_list) - [Modified `process_execution_payload`](#modified-process_execution_payload) - [Operations](#operations) - [Modified `process_operations`](#modified-process_operations) @@ -990,8 +991,8 @@ class NewPayloadRequest(object): ```python def notify_new_payload(self: ExecutionEngine, execution_payload: ExecutionPayload, - execution_requests: ExecutionRequests, - parent_beacon_block_root: Root) -> bool: + parent_beacon_block_root: Root, + execution_requests_list: list[bytes]) -> bool: """ Return ``True`` if and only if ``execution_payload`` and ``execution_requests`` are valid with respect to ``self.execution_state``. @@ -1011,8 +1012,8 @@ def verify_and_notify_new_payload(self: ExecutionEngine, Return ``True`` if and only if ``new_payload_request`` is valid with respect to ``self.execution_state``. """ execution_payload = new_payload_request.execution_payload - execution_requests = new_payload_request.execution_requests # [New in Electra] parent_beacon_block_root = new_payload_request.parent_beacon_block_root + execution_requests_list = get_execution_requests_list(new_payload_request.execution_requests) # [New in Electra] if not self.is_valid_block_hash(execution_payload, parent_beacon_block_root): return False @@ -1022,9 +1023,9 @@ def verify_and_notify_new_payload(self: ExecutionEngine, # [Modified in Electra] if not self.notify_new_payload( - execution_payload, - execution_requests, - parent_beacon_block_root): + execution_payload, + parent_beacon_block_root, + execution_requests_list): return False return True @@ -1139,6 +1140,19 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None: #### Execution payload +##### New `get_execution_requests_list` + +*Note*: Encodes execution requests as defined by [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685). + +```python +def get_execution_requests_list(execution_requests: ExecutionRequests) -> list[bytes]: + deposit_bytes = serialize(execution_requests.deposits) + withdrawal_bytes = serialize(execution_requests.withdrawals) + consolidation_bytes = serialize(execution_requests.consolidations) + + return [deposit_bytes, withdrawal_bytes, consolidation_bytes] +``` + ##### 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`). @@ -1160,9 +1174,9 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi 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, + execution_requests=body.execution_requests, # [New in Electra] ) ) # Cache execution payload header diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index d1cdd9f1e4..93244d44a1 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.5.0-alpha.7 +1.5.0-alpha.8 diff --git a/tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_blocks.py b/tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_blocks.py index 0bb8f32d46..c3d2284610 100644 --- a/tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_blocks.py @@ -28,13 +28,13 @@ def test_basic_el_withdrawal_request(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - yield 'pre', state - validator_index = 0 address = b'\x22' * 20 set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address) assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH + yield 'pre', state + validator_pubkey = state.validators[validator_index].pubkey withdrawal_request = spec.WithdrawalRequest( source_address=address, @@ -57,10 +57,11 @@ def test_basic_btec_and_el_withdrawal_request_in_same_block(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - yield 'pre', state validator_index = 0 assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH + yield 'pre', state + block = build_empty_block_for_next_slot(spec, state) address = b'\x22' * 20 @@ -99,11 +100,11 @@ def test_basic_btec_before_el_withdrawal_request(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - yield 'pre', state - validator_index = 0 assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH + yield 'pre', state + # block_1 contains a BTEC operation of the given validator address = b'\x22' * 20 signed_address_change = get_signed_address_change( @@ -146,13 +147,13 @@ def test_cl_exit_and_el_withdrawal_request_in_same_block(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - yield 'pre', state - validator_index = 0 address = b'\x22' * 20 set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address) assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH + yield 'pre', state + # CL-Exit signed_voluntary_exits = prepare_signed_exits(spec, state, indices=[validator_index]) # EL-Exit diff --git a/tests/generators/operations/main.py b/tests/generators/operations/main.py index 51cd507066..ae66843f61 100644 --- a/tests/generators/operations/main.py +++ b/tests/generators/operations/main.py @@ -49,6 +49,7 @@ 'deposit_request', 'voluntary_exit', 'withdrawal_request', + 'withdrawals', ]} electra_mods = combine_mods(_new_electra_mods, deneb_mods)