From da7b3cef8f88e358987f6d8f270976fd2427d0e4 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 28 Sep 2021 09:15:59 +1000 Subject: [PATCH 01/12] Add "P2P Networking" to "Merge" section --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9e5d7dc428..1ae37766f4 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ The merge is still actively in development. The exact specification has not been * [Fork Choice changes](specs/merge/fork-choice.md) * [Validator additions](specs/merge/validator.md) * [Client settings](specs/merge/client-settings.md) + * [P2P Networking](specs/merge/p2p-interface.md) ### Sharding From 6d81440b10432c43fe7de5d79c8f3cc42368480f Mon Sep 17 00:00:00 2001 From: terence tsao Date: Mon, 27 Sep 2021 21:19:03 -0700 Subject: [PATCH 02/12] Fix a comment typo in `execute_payload` --- specs/merge/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 56476cedd1..659f4c6300 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -257,7 +257,7 @@ The Engine API may be used to implement them with an external execution engine. ```python def execute_payload(self: ExecutionEngine, execution_payload: ExecutionPayload) -> bool: """ - Returns ``True`` iff ``execution_payload`` is valid with respect to ``self.execution_state``. + Returns ``True`` if ``execution_payload`` is valid with respect to ``self.execution_state``. """ ... ``` From 2ea262f7d6485ad26a8185768d909c60eebf19a9 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Tue, 28 Sep 2021 07:53:29 -0700 Subject: [PATCH 03/12] Update specs/merge/beacon-chain.md Co-authored-by: Hsiao-Wei Wang --- specs/merge/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 659f4c6300..02ea1b24ff 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -257,7 +257,7 @@ The Engine API may be used to implement them with an external execution engine. ```python def execute_payload(self: ExecutionEngine, execution_payload: ExecutionPayload) -> bool: """ - Returns ``True`` if ``execution_payload`` is valid with respect to ``self.execution_state``. + Return ``True`` if and only if ``execution_payload`` is valid with respect to ``self.execution_state``. """ ... ``` From 2d169adfc73b3cdf89e1e90e7b736bbfca10fe25 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 29 Sep 2021 01:10:09 +0800 Subject: [PATCH 04/12] Fix `initialize_beacon_state_from_eth1` previous_version --- specs/merge/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 56476cedd1..083bdd00aa 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -362,7 +362,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: fork = Fork( - previous_version=GENESIS_FORK_VERSION, + previous_version=ALTAIR_FORK_VERSION, current_version=MERGE_FORK_VERSION, # [Modified in Merge] epoch=GENESIS_EPOCH, ) From 939e6c7e8eab56a8cce197b5d25218026198b0c9 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Tue, 28 Sep 2021 23:30:29 +0200 Subject: [PATCH 05/12] run tests against future forks by default Some tests are currently restricted to a single phase using @with_phases even though they could likely run unchanged in later phases. This patch changes the default for such tests to also run in later phases. If the beacon chain changes enough in later phases to break these tests, this highlights that the tests need to be adjusted or extended accordingly. --- .../test/altair/merkle/test_single_proof.py | 7 +++---- .../altair/unittests/networking/test_networking.py | 2 +- .../test/altair/unittests/test_config_invariants.py | 7 +++---- .../test/altair/unittests/test_sync_protocol.py | 13 +++++-------- tests/core/pyspec/eth2spec/test/context.py | 4 ++-- tests/generators/merkle/main.py | 6 ++++-- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/altair/merkle/test_single_proof.py b/tests/core/pyspec/eth2spec/test/altair/merkle/test_single_proof.py index f9aa68adda..31cdd13bb1 100644 --- a/tests/core/pyspec/eth2spec/test/altair/merkle/test_single_proof.py +++ b/tests/core/pyspec/eth2spec/test/altair/merkle/test_single_proof.py @@ -1,12 +1,11 @@ from eth2spec.test.context import ( spec_state_test, - with_phases, + with_altair_and_later, ) -from eth2spec.test.helpers.constants import ALTAIR from eth2spec.test.helpers.merkle import build_proof -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test def test_next_sync_committee_merkle_proof(spec, state): yield "state", state @@ -25,7 +24,7 @@ def test_next_sync_committee_merkle_proof(spec, state): ) -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test def test_finality_root_merkle_proof(spec, state): yield "state", state diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/networking/test_networking.py b/tests/core/pyspec/eth2spec/test/altair/unittests/networking/test_networking.py index 37d50611dc..6d9dca5237 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/networking/test_networking.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/networking/test_networking.py @@ -1,6 +1,6 @@ from eth2spec.test.context import ( - with_altair_and_later, spec_state_test, + with_altair_and_later, ) from eth2spec.test.helpers.state import ( transition_to, diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/test_config_invariants.py b/tests/core/pyspec/eth2spec/test/altair/unittests/test_config_invariants.py index 4443f97e0b..91be0a0a61 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/test_config_invariants.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/test_config_invariants.py @@ -1,11 +1,10 @@ from eth2spec.test.context import ( spec_state_test, - with_phases, + with_altair_and_later, ) -from eth2spec.test.helpers.constants import ALTAIR -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test def test_weight_denominator(spec, state): assert ( @@ -17,7 +16,7 @@ def test_weight_denominator(spec, state): ) == spec.WEIGHT_DENOMINATOR -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test def test_inactivity_score(spec, state): assert spec.config.INACTIVITY_SCORE_BIAS <= spec.config.INACTIVITY_SCORE_RECOVERY_RATE diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py index c69957de53..15444df819 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py @@ -1,17 +1,14 @@ from eth2spec.test.context import ( spec_state_test, with_presets, - with_phases, + with_altair_and_later, ) from eth2spec.test.helpers.attestations import next_epoch_with_attestations from eth2spec.test.helpers.block import ( build_empty_block, build_empty_block_for_next_slot, ) -from eth2spec.test.helpers.constants import ( - ALTAIR, - MINIMAL, -) +from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.helpers.state import ( next_slots, state_transition_and_sign_block, @@ -22,7 +19,7 @@ from eth2spec.test.helpers.merkle import build_proof -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test def test_process_light_client_update_not_updated(spec, state): pre_snapshot = spec.LightClientSnapshot( @@ -81,7 +78,7 @@ def test_process_light_client_update_not_updated(spec, state): assert store.snapshot == pre_snapshot -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_timeout(spec, state): @@ -147,7 +144,7 @@ def test_process_light_client_update_timeout(spec, state): assert store.snapshot.header == update.header -@with_phases([ALTAIR]) +@with_altair_and_later @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_finality_updated(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index ef92efaded..6062648d60 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -463,8 +463,8 @@ def is_post_merge(spec): return spec.fork not in FORKS_BEFORE_MERGE -with_altair_and_later = with_phases([ALTAIR, MERGE]) -with_merge_and_later = with_phases([MERGE]) # TODO: include sharding when spec stabilizes. +with_altair_and_later = with_all_phases_except([PHASE0]) +with_merge_and_later = with_all_phases_except([PHASE0, ALTAIR]) def only_generator(reason): diff --git a/tests/generators/merkle/main.py b/tests/generators/merkle/main.py index 7203c5f193..44fbec10c6 100644 --- a/tests/generators/merkle/main.py +++ b/tests/generators/merkle/main.py @@ -1,4 +1,4 @@ -from eth2spec.test.helpers.constants import ALTAIR +from eth2spec.test.helpers.constants import ALTAIR, MERGE from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators @@ -6,9 +6,11 @@ altair_mods = {key: 'eth2spec.test.altair.merkle.test_' + key for key in [ 'single_proof', ]} + merge_mods = altair_mods all_mods = { - ALTAIR: altair_mods + ALTAIR: altair_mods, + MERGE: merge_mods, } run_state_test_generators(runner_name="merkle", all_mods=all_mods) From 1f7040b42b0b6197cc071bebc7a06138cb28c928 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 30 Sep 2021 16:41:05 +0800 Subject: [PATCH 06/12] Make previous_version=current_version --- specs/altair/beacon-chain.md | 2 +- specs/merge/beacon-chain.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/altair/beacon-chain.md b/specs/altair/beacon-chain.md index dbd3e63683..b22f89a4db 100644 --- a/specs/altair/beacon-chain.md +++ b/specs/altair/beacon-chain.md @@ -689,7 +689,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: fork = Fork( - previous_version=GENESIS_FORK_VERSION, + previous_version=ALTAIR_FORK_VERSION, # [Modified in Altair] for testing only current_version=ALTAIR_FORK_VERSION, # [Modified in Altair] epoch=GENESIS_EPOCH, ) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 083bdd00aa..9fc01019b0 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -362,7 +362,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: fork = Fork( - previous_version=ALTAIR_FORK_VERSION, + previous_version=MERGE_FORK_VERSION, # [Modified in Merge] for testing only current_version=MERGE_FORK_VERSION, # [Modified in Merge] epoch=GENESIS_EPOCH, ) From 65649c0383c886b11beac6f0fb58bad19ffc2f7e Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 1 Oct 2021 14:52:30 +0200 Subject: [PATCH 07/12] use correct timestamp for empty ExecutionPayload There are two similar functions to compute the timestamp for a given beacon chain slot. `compute_time_at_slot` is used for processing Eth1 votes, and does not take into account `GENESIS_TIME`. The other one, `compute_timestamp_at_slot`, is used everywhere else. When processing `ExecutionPayload`, the `merge/beacon-chain.md` spec uses the latter, `compute_timestamp_at_slot`, to verify the timestamp. However, in the test code, `build_empty_execution_payload` uses `compute_time_at_slot`. This patch changes the test to use the same function for creating the timestamp that is later used to verify it. Note that `GENESIS_TIME` is 0 so there is no practical difference. --- tests/core/pyspec/eth2spec/test/helpers/execution_payload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 0d03447a76..59308e102a 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -3,7 +3,7 @@ def build_empty_execution_payload(spec, state, randao_mix=None): Assuming a pre-state of the same slot, build a valid ExecutionPayload without any transactions. """ latest = state.latest_execution_payload_header - timestamp = spec.compute_time_at_slot(state, state.slot) + timestamp = spec.compute_timestamp_at_slot(state, state.slot) empty_txs = spec.List[spec.Transaction, spec.MAX_TRANSACTIONS_PER_PAYLOAD]() if randao_mix is None: From af262bec07bbcf25303704b7650ab9da85f1ff69 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 3 Oct 2021 15:12:59 +0300 Subject: [PATCH 08/12] make initialize_beacon_state_from_eth1 work for pre-transition merge --- specs/merge/beacon-chain.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 16f3278acf..275d29a0a1 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -354,13 +354,18 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe ## Testing *Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Merge testing only. - -*Note*: The function `initialize_beacon_state_from_eth1` is modified: (1) using `MERGE_FORK_VERSION` as the current fork version, (2) utilizing the Merge `BeaconBlockBody` when constructing the initial `latest_block_header`, and (3) initialize `latest_execution_payload_header`. +Modifications include: +1. Use `MERGE_FORK_VERSION` as the current fork version +2. Utilize the Merge `BeaconBlockBody` when constructing the initial `latest_block_header` +3. Initialize `latest_execution_payload_header`. + If `execution_payload_header == ExecutionPayloadHeader()`, then the Merge has not yet occurred. + Else, the Merge starts from genesis. ```python def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, eth1_timestamp: uint64, - deposits: Sequence[Deposit]) -> BeaconState: + deposits: Sequence[Deposit], + execution_payload_header: ExecutionPayloadHeader) -> BeaconState: fork = Fork( previous_version=MERGE_FORK_VERSION, # [Modified in Merge] for testing only current_version=MERGE_FORK_VERSION, # [Modified in Merge] @@ -397,12 +402,8 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, state.current_sync_committee = get_next_sync_committee(state) state.next_sync_committee = get_next_sync_committee(state) - # [New in Merge] Initialize the execution payload header (with block number set to 0) - state.latest_execution_payload_header.block_hash = eth1_block_hash - state.latest_execution_payload_header.timestamp = eth1_timestamp - state.latest_execution_payload_header.random = eth1_block_hash - state.latest_execution_payload_header.gas_limit = GENESIS_GAS_LIMIT - state.latest_execution_payload_header.base_fee_per_gas = GENESIS_BASE_FEE_PER_GAS + # [New in Merge] Initialize the execution payload header + state.latest_execution_payload_header = execution_payload_header return state ``` From 789eea0060285c5b771cb2cca7f046c69afa2d36 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 3 Oct 2021 16:16:59 +0300 Subject: [PATCH 09/12] fix tests. add new generator --- specs/merge/beacon-chain.md | 4 +- .../test/merge/genesis/test_initialization.py | 129 ++++++++++++++++++ tests/formats/genesis/initialization.md | 7 +- 3 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 275d29a0a1..29718b0ec1 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 0000000000..853d635c7f --- /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 73630de51c..e7edec173d 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`: From e235aa82961e0143fa840c72b176cfa03162c71b Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 3 Oct 2021 22:20:53 +0800 Subject: [PATCH 10/12] Clean up. Add `execution_payload_header` to initialization `meta.yaml` --- specs/merge/beacon-chain.md | 6 +++--- .../eth2spec/test/merge/genesis/__init__.py | 0 .../test/merge/genesis/test_initialization.py | 21 +++++++++++-------- tests/formats/genesis/initialization.md | 5 +++-- tests/generators/genesis/main.py | 7 ++++++- 5 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/merge/genesis/__init__.py diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 29718b0ec1..3e2fd9753a 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -355,11 +355,11 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe *Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Merge testing only. Modifications include: -1. Use `MERGE_FORK_VERSION` as the current fork version -2. Utilize the Merge `BeaconBlockBody` when constructing the initial `latest_block_header` +1. Use `MERGE_FORK_VERSION` as the current fork version. +2. Utilize the Merge `BeaconBlockBody` when constructing the initial `latest_block_header`. 3. Initialize `latest_execution_payload_header`. If `execution_payload_header == ExecutionPayloadHeader()`, then the Merge has not yet occurred. - Else, the Merge starts from genesis. + Else, the Merge starts from genesis and the transition is incomplete. ```python def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32, diff --git a/tests/core/pyspec/eth2spec/test/merge/genesis/__init__.py b/tests/core/pyspec/eth2spec/test/merge/genesis/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py b/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py index 853d635c7f..384bf57c40 100644 --- a/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py +++ b/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py @@ -1,7 +1,9 @@ from eth2spec.test.context import ( + MERGE, single_phase, spec_test, with_presets, + with_phases, with_merge_and_later, ) from eth2spec.test.helpers.constants import MINIMAL @@ -17,7 +19,7 @@ def eth1_init_data(eth1_block_hash, eth1_timestamp): } -@with_merge_and_later +@with_phases([MERGE]) @spec_test @single_phase @with_presets([MINIMAL], reason="too slow") @@ -37,11 +39,11 @@ def test_initialize_pre_transition_no_param(spec): yield 'deposits', deposits # initialize beacon_state *without* an execution_payload_header + yield 'execution_payload_header', 'meta', False state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) - assert not spec.is_merge_comp(state) + assert not spec.is_merge_complete(state) - # yield state yield 'state', state @@ -64,19 +66,20 @@ def test_initialize_pre_transition_empty_payload(spec): yield from eth1_init_data(eth1_block_hash, eth1_timestamp) yield 'deposits', deposits - # initialize beacon_state *without* an execution_payload_header + # initialize beacon_state *with* an *empty* execution_payload_header + yield 'execution_payload_header', 'meta', True + execution_payload_header = spec.ExecutionPayloadHeader() state = spec.initialize_beacon_state_from_eth1( eth1_block_hash, eth1_timestamp, deposits, - spec.ExecutionPayloadHeader() + execution_payload_header=execution_payload_header, ) assert not spec.is_merge_complete(state) - yield 'execution_payload_header', spec.ExecutionPayloadHeader() + yield 'execution_payload_header', execution_payload_header - # yield state yield 'state', state @@ -100,6 +103,7 @@ def test_initialize_post_transition(spec): yield 'deposits', deposits # initialize beacon_state *with* an execution_payload_header + yield 'execution_payload_header', 'meta', True genesis_execution_payload_header = spec.ExecutionPayloadHeader( parent_hash=b'\x30' * 32, coinbase=b'\x42' * 20, @@ -118,12 +122,11 @@ def test_initialize_post_transition(spec): eth1_block_hash, eth1_timestamp, deposits, - genesis_execution_payload_header, + execution_payload_header=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 e7edec173d..d0d453e5b6 100644 --- a/tests/formats/genesis/initialization.md +++ b/tests/formats/genesis/initialization.md @@ -17,8 +17,9 @@ eth1_timestamp: int -- An integer. The timestamp of the block, in seconds. A yaml file to help read the deposit count: ```yaml -description: string -- Optional. Description of test case, purely for debugging purposes. -deposits_count: int -- Amount of deposits. +description: string -- Optional. Description of test case, purely for debugging purposes. +deposits_count: int -- Amount of deposits. +execution_payload_header: bool -- `execution_payload_header` field is filled or not. If `true`, `execution_payload_header.ssz_snappy` file exists. ``` ### `deposits_.ssz_snappy` diff --git a/tests/generators/genesis/main.py b/tests/generators/genesis/main.py index 1f36afd4b9..a595db6120 100644 --- a/tests/generators/genesis/main.py +++ b/tests/generators/genesis/main.py @@ -9,7 +9,12 @@ ]} altair_mods = phase_0_mods # we have new unconditional lines in `initialize_beacon_state_from_eth1` and we want to test it - merge_mods = altair_mods + merge_mods = { + **{key: 'eth2spec.test.merge.genesis.test_' + key for key in [ + 'initialization', + ]}, + **altair_mods, + } all_mods = { PHASE0: phase_0_mods, ALTAIR: altair_mods, From f1f082fbe7d74aea726a02c0c5f9613a5de58ebc Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 4 Oct 2021 00:30:01 +0800 Subject: [PATCH 11/12] Remove the unused stub constants --- specs/merge/beacon-chain.md | 10 ------- .../pyspec/eth2spec/test/helpers/genesis.py | 27 ++++++++++++++++--- .../test/merge/genesis/test_initialization.py | 18 +++---------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 3e2fd9753a..b3d1848552 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -13,7 +13,6 @@ - [Constants](#constants) - [Execution](#execution) - [Configuration](#configuration) - - [Genesis testing settings](#genesis-testing-settings) - [Transition settings](#transition-settings) - [Containers](#containers) - [Extended containers](#extended-containers) @@ -71,15 +70,6 @@ This patch adds transaction execution to the beacon chain as part of the Merge f ## Configuration -### Genesis testing settings - -*Note*: These configuration settings do not apply to the mainnet and are utilized only by pure Merge testing. - -| Name | Value | -| - | - | -| `GENESIS_GAS_LIMIT` | `uint64(30000000)` (= 30,000,000) | -| `GENESIS_BASE_FEE_PER_GAS` | `Bytes32('0x00ca9a3b00000000000000000000000000000000000000000000000000000000')` (= 1,000,000,000) | - ### Transition settings | Name | Value | diff --git a/tests/core/pyspec/eth2spec/test/helpers/genesis.py b/tests/core/pyspec/eth2spec/test/helpers/genesis.py index 0e9af4cff9..cd96c8168f 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/genesis.py +++ b/tests/core/pyspec/eth2spec/test/helpers/genesis.py @@ -20,6 +20,25 @@ def build_mock_validator(spec, i: int, balance: int): ) +def get_sample_genesis_execution_payload_header(spec, + eth1_block_hash=None): + if eth1_block_hash is None: + eth1_block_hash = b'\x55' * 32 + return 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=eth1_block_hash, + block_number=0, + gas_limit=30000000, + base_fee_per_gas=spec.Bytes32('0x00ca9a3b00000000000000000000000000000000000000000000000000000000'), + block_hash=eth1_block_hash, + transactions_root=spec.Root(b'\x56' * 32), + ) + + def create_genesis_state(spec, validator_balances, activation_threshold): deposit_root = b'\x42' * 32 @@ -76,9 +95,9 @@ def create_genesis_state(spec, validator_balances, activation_threshold): if spec.fork not in FORKS_BEFORE_MERGE: # Initialize the execution payload header (with block number and genesis time set to 0) - state.latest_execution_payload_header.block_hash = eth1_block_hash - state.latest_execution_payload_header.random = eth1_block_hash - state.latest_execution_payload_header.gas_limit = spec.GENESIS_GAS_LIMIT - state.latest_execution_payload_header.base_fee_per_gas = spec.GENESIS_BASE_FEE_PER_GAS + state.latest_execution_payload_header = get_sample_genesis_execution_payload_header( + spec, + eth1_block_hash=eth1_block_hash, + ) 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 index 384bf57c40..78462263b2 100644 --- a/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py +++ b/tests/core/pyspec/eth2spec/test/merge/genesis/test_initialization.py @@ -10,6 +10,9 @@ from eth2spec.test.helpers.deposits import ( prepare_full_genesis_deposits, ) +from eth2spec.test.helpers.genesis import ( + get_sample_genesis_execution_payload_header, +) def eth1_init_data(eth1_block_hash, eth1_timestamp): @@ -104,20 +107,7 @@ def test_initialize_post_transition(spec): # initialize beacon_state *with* an execution_payload_header yield 'execution_payload_header', 'meta', True - 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), - - ) + genesis_execution_payload_header = get_sample_genesis_execution_payload_header(spec) state = spec.initialize_beacon_state_from_eth1( eth1_block_hash, eth1_timestamp, From dd6f09dab8e3e0c7ec1fc24db3c309eb2e6f4258 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 4 Oct 2021 08:06:04 +0300 Subject: [PATCH 12/12] bump version.txt to v1.1.1 --- tests/core/pyspec/eth2spec/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index 1cc5f657e0..8cfbc905b3 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.1.0 \ No newline at end of file +1.1.1 \ No newline at end of file