From e793fe26985dfaee973f9734b70589e63724ffd2 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 24 Apr 2024 20:08:56 +0800 Subject: [PATCH] Add Electra fork tests --- .../eth2spec/test/electra/fork/__init__.py | 0 .../electra/fork/test_electra_fork_basic.py | 82 ++++++++++++++++++ .../electra/fork/test_electra_fork_random.py | 84 +++++++++++++++++++ .../eth2spec/test/helpers/deneb/fork.py | 2 + .../eth2spec/test/helpers/electra/__init__.py | 0 .../eth2spec/test/helpers/electra/fork.py | 65 ++++++++++++++ tests/generators/forks/main.py | 5 +- 7 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 tests/core/pyspec/eth2spec/test/electra/fork/__init__.py create mode 100644 tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_basic.py create mode 100644 tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_random.py create mode 100644 tests/core/pyspec/eth2spec/test/helpers/electra/__init__.py create mode 100644 tests/core/pyspec/eth2spec/test/helpers/electra/fork.py diff --git a/tests/core/pyspec/eth2spec/test/electra/fork/__init__.py b/tests/core/pyspec/eth2spec/test/electra/fork/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_basic.py b/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_basic.py new file mode 100644 index 000000000..3bd6350b3 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_basic.py @@ -0,0 +1,82 @@ +from eth2spec.test.context import ( + with_phases, + with_custom_state, + with_presets, + spec_test, with_state, + low_balances, misc_balances, large_validator_set, +) +from eth2spec.test.utils import with_meta_tags +from eth2spec.test.helpers.constants import ( + DENEB, ELECTRA, + MINIMAL, +) +from eth2spec.test.helpers.state import ( + next_epoch, + next_epoch_via_block, +) +from eth2spec.test.helpers.electra.fork import ( + ELECTRA_FORK_TEST_META_TAGS, + run_fork_test, +) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_base_state(spec, phases, state): + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_next_epoch(spec, phases, state): + next_epoch(spec, state) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_next_epoch_with_block(spec, phases, state): + next_epoch_via_block(spec, state) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_many_next_epoch(spec, phases, state): + for _ in range(3): + next_epoch(spec, state) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@spec_test +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_random_low_balances(spec, phases, state): + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@spec_test +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_random_misc_balances(spec, phases, state): + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@with_presets([MINIMAL], + reason="mainnet config leads to larger validator set than limit of public/private keys pre-generated") +@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@spec_test +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_fork_random_large_validator_set(spec, phases, state): + yield from run_fork_test(phases[ELECTRA], state) diff --git a/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_random.py b/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_random.py new file mode 100644 index 000000000..07495ed45 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/electra/fork/test_electra_fork_random.py @@ -0,0 +1,84 @@ +from random import Random + +from eth2spec.test.context import ( + with_phases, + with_custom_state, + with_presets, + spec_test, with_state, + low_balances, misc_balances, large_validator_set, +) +from eth2spec.test.utils import with_meta_tags +from eth2spec.test.helpers.constants import ( + DENEB, ELECTRA, + MINIMAL, +) +from eth2spec.test.helpers.electra.fork import ( + ELECTRA_FORK_TEST_META_TAGS, + run_fork_test, +) +from eth2spec.test.helpers.random import randomize_state + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_0(spec, phases, state): + randomize_state(spec, state, rng=Random(1010)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_1(spec, phases, state): + randomize_state(spec, state, rng=Random(2020)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_2(spec, phases, state): + randomize_state(spec, state, rng=Random(3030)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_state +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_3(spec, phases, state): + randomize_state(spec, state, rng=Random(4040)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_low_balances(spec, phases, state): + randomize_state(spec, state, rng=Random(5050)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@spec_test +@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_misc_balances(spec, phases, state): + randomize_state(spec, state, rng=Random(6060)) + yield from run_fork_test(phases[ELECTRA], state) + + +@with_phases(phases=[DENEB], other_phases=[ELECTRA]) +@with_presets([MINIMAL], + reason="mainnet config leads to larger validator set than limit of public/private keys pre-generated") +@spec_test +@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE) +@with_meta_tags(ELECTRA_FORK_TEST_META_TAGS) +def test_electra_fork_random_large_validator_set(spec, phases, state): + randomize_state(spec, state, rng=Random(7070)) + yield from run_fork_test(phases[ELECTRA], state) diff --git a/tests/core/pyspec/eth2spec/test/helpers/deneb/fork.py b/tests/core/pyspec/eth2spec/test/helpers/deneb/fork.py index 7fe0535c1..fd2428a04 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/deneb/fork.py +++ b/tests/core/pyspec/eth2spec/test/helpers/deneb/fork.py @@ -36,6 +36,8 @@ def run_fork_test(post_spec, pre_state): 'current_sync_committee', 'next_sync_committee', # Withdrawals 'next_withdrawal_index', 'next_withdrawal_validator_index', + # Deep history valid from Capella onwards + 'historical_summaries', ] for field in stable_fields: assert getattr(pre_state, field) == getattr(post_state, field) diff --git a/tests/core/pyspec/eth2spec/test/helpers/electra/__init__.py b/tests/core/pyspec/eth2spec/test/helpers/electra/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/core/pyspec/eth2spec/test/helpers/electra/fork.py b/tests/core/pyspec/eth2spec/test/helpers/electra/fork.py new file mode 100644 index 000000000..39a43a523 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/helpers/electra/fork.py @@ -0,0 +1,65 @@ +from eth2spec.test.helpers.constants import ( + ELECTRA, +) + + +ELECTRA_FORK_TEST_META_TAGS = { + 'fork': ELECTRA, +} + + +def run_fork_test(post_spec, pre_state): + yield 'pre', pre_state + + post_state = post_spec.upgrade_to_electra(pre_state) + + # Stable fields + stable_fields = [ + 'genesis_time', 'genesis_validators_root', 'slot', + # History + 'latest_block_header', 'block_roots', 'state_roots', 'historical_roots', + # Eth1 + 'eth1_data', 'eth1_data_votes', 'eth1_deposit_index', + # Registry + # NOTE: 'validators', 'balances' could be changed. + # Randomness + 'randao_mixes', + # Slashings + 'slashings', + # Participation + 'previous_epoch_participation', 'current_epoch_participation', + # Finality + 'justification_bits', 'previous_justified_checkpoint', 'current_justified_checkpoint', 'finalized_checkpoint', + # Inactivity + 'inactivity_scores', + # Sync + 'current_sync_committee', 'next_sync_committee', + # Withdrawals + 'next_withdrawal_index', 'next_withdrawal_validator_index', + # Deep history valid from Capella onwards + 'historical_summaries', + + ] + for field in stable_fields: + assert getattr(pre_state, field) == getattr(post_state, field) + + # Modified fields + modified_fields = ['fork', 'latest_execution_payload_header'] + for field in modified_fields: + assert getattr(pre_state, field) != getattr(post_state, field) + + assert len(pre_state.validators) == len(post_state.validators) + for pre_validator, post_validator in zip(pre_state.validators, post_state.validators): + stable_validator_fields = [ + 'pubkey', 'withdrawal_credentials', + 'slashed', + 'exit_epoch', 'withdrawable_epoch', + ] + for field in stable_validator_fields: + assert getattr(pre_validator, field) == getattr(post_validator, field) + + assert pre_state.fork.current_version == post_state.fork.previous_version + assert post_state.fork.current_version == post_spec.config.ELECTRA_FORK_VERSION + assert post_state.fork.epoch == post_spec.get_current_epoch(post_state) + + yield 'post', post_state diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index 7d68a31e7..91078c8da 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -1,7 +1,7 @@ from typing import Iterable from eth2spec.test.helpers.constants import ( - PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, + PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, ELECTRA, MINIMAL, MAINNET, ) from eth2spec.test.helpers.typing import SpecForkName, PresetBaseName @@ -9,6 +9,7 @@ from eth2spec.test.altair.fork import test_altair_fork_basic, test_altair_fork_r from eth2spec.test.bellatrix.fork import test_bellatrix_fork_basic, test_bellatrix_fork_random from eth2spec.test.capella.fork import test_capella_fork_basic, test_capella_fork_random from eth2spec.test.deneb.fork import test_deneb_fork_basic, test_deneb_fork_random +from eth2spec.test.electra.fork import test_electra_fork_basic, test_electra_fork_random from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests @@ -42,6 +43,8 @@ def _get_fork_tests_providers(): yield create_provider(test_capella_fork_random, preset, BELLATRIX, CAPELLA) yield create_provider(test_deneb_fork_basic, preset, CAPELLA, DENEB) yield create_provider(test_deneb_fork_random, preset, CAPELLA, DENEB) + yield create_provider(test_electra_fork_basic, preset, DENEB, ELECTRA) + yield create_provider(test_electra_fork_random, preset, DENEB, ELECTRA) if __name__ == "__main__":