diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 275d29a0a..29718b0ec 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -365,7 +365,8 @@ Modifications include: def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, eth1_timestamp: uint64, deposits: Sequence[Deposit], - execution_payload_header: ExecutionPayloadHeader) -> BeaconState: + execution_payload_header: ExecutionPayloadHeader=ExecutionPayloadHeader() + ) -> BeaconState: fork = Fork( previous_version=MERGE_FORK_VERSION, # [Modified in Merge] for testing only current_version=MERGE_FORK_VERSION, # [Modified in Merge] @@ -403,6 +404,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, state.next_sync_committee = get_next_sync_committee(state) # [New in Merge] Initialize the execution payload header + # If empty, will initialize a chain that has not yet gone through the Merge transition state.latest_execution_payload_header = execution_payload_header return state diff --git a/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py b/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py new file mode 100644 index 000000000..853d635c7 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py @@ -0,0 +1,129 @@ +from eth2spec.test.context import ( + single_phase, + spec_test, + with_presets, + with_merge_and_later, +) +from eth2spec.test.helpers.constants import MINIMAL +from eth2spec.test.helpers.deposits import ( + prepare_full_genesis_deposits, +) + + +def eth1_init_data(eth1_block_hash, eth1_timestamp): + yield 'eth1', { + 'eth1_block_hash': '0x' + eth1_block_hash.hex(), + 'eth1_timestamp': int(eth1_timestamp), + } + + +@with_merge_and_later +@spec_test +@single_phase +@with_presets([MINIMAL], reason="too slow") +def test_initialize_pre_transition_no_param(spec): + deposit_count = spec.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, deposit_root, _ = prepare_full_genesis_deposits( + spec, + spec.MAX_EFFECTIVE_BALANCE, + deposit_count, + signed=True, + ) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.config.MIN_GENESIS_TIME + + yield from eth1_init_data(eth1_block_hash, eth1_timestamp) + yield 'deposits', deposits + + # initialize beacon_state *without* an execution_payload_header + state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + assert not spec.is_merge_comp(state) + + # yield state + yield 'state', state + + +@with_merge_and_later +@spec_test +@single_phase +@with_presets([MINIMAL], reason="too slow") +def test_initialize_pre_transition_empty_payload(spec): + deposit_count = spec.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, deposit_root, _ = prepare_full_genesis_deposits( + spec, + spec.MAX_EFFECTIVE_BALANCE, + deposit_count, + signed=True, + ) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.config.MIN_GENESIS_TIME + + yield from eth1_init_data(eth1_block_hash, eth1_timestamp) + yield 'deposits', deposits + + # initialize beacon_state *without* an execution_payload_header + state = spec.initialize_beacon_state_from_eth1( + eth1_block_hash, + eth1_timestamp, + deposits, + spec.ExecutionPayloadHeader() + ) + + assert not spec.is_merge_complete(state) + + yield 'execution_payload_header', spec.ExecutionPayloadHeader() + + # yield state + yield 'state', state + + +@with_merge_and_later +@spec_test +@single_phase +@with_presets([MINIMAL], reason="too slow") +def test_initialize_post_transition(spec): + deposit_count = spec.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, deposit_root, _ = prepare_full_genesis_deposits( + spec, + spec.MAX_EFFECTIVE_BALANCE, + deposit_count, + signed=True, + ) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.config.MIN_GENESIS_TIME + + yield from eth1_init_data(eth1_block_hash, eth1_timestamp) + yield 'deposits', deposits + + # initialize beacon_state *with* an execution_payload_header + genesis_execution_payload_header = spec.ExecutionPayloadHeader( + parent_hash=b'\x30' * 32, + coinbase=b'\x42' * 20, + state_root=b'\x20' * 32, + receipt_root=b'\x20' * 32, + logs_bloom=b'\x35' * spec.BYTES_PER_LOGS_BLOOM, + random=b'\x55' * 32, + block_number=0, + gas_limit=30000000, + base_fee_per_gas=b'\x10' * 32, + block_hash=b'\x99' * 32, + transactions_root=spec.Root(b'\x56' * 32), + + ) + state = spec.initialize_beacon_state_from_eth1( + eth1_block_hash, + eth1_timestamp, + deposits, + genesis_execution_payload_header, + ) + + yield 'execution_payload_header', genesis_execution_payload_header + + assert spec.is_merge_complete(state) + + # yield state + yield 'state', state diff --git a/tests/formats/genesis/initialization.md b/tests/formats/genesis/initialization.md index 73630de51..e7edec173 100644 --- a/tests/formats/genesis/initialization.md +++ b/tests/formats/genesis/initialization.md @@ -26,11 +26,16 @@ deposits_count: int -- Amount of deposits. A series of files, with `` in range `[0, deposits_count)`. Deposits need to be processed in order. Each file is a SSZ-snappy encoded `Deposit` object. +### `execution_payload_header.ssz_snappy` + +*Note*: Param added only for the Merge and subsequent forks. + +The execution payload header that state is initialized with. An SSZ-snappy encoded `BeaconState` object. + ### `state.ssz_snappy` The expected genesis state. An SSZ-snappy encoded `BeaconState` object. - ## Processing To process this test, build a genesis state with the provided `eth1_block_hash`, `eth1_timestamp` and `deposits`: