From 9c798806355f67a32704a8cd5a98d90deccb8f69 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 15 Jul 2022 22:18:33 +0800 Subject: [PATCH 1/2] Fix genesis testing tool and add Capella version `initialize_beacon_state_from_eth1` helper --- specs/capella/beacon-chain.md | 57 +++++++++++++++++++ .../pyspec/eth2spec/test/helpers/genesis.py | 5 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/specs/capella/beacon-chain.md b/specs/capella/beacon-chain.md index da67a8fcb..ca0305f04 100644 --- a/specs/capella/beacon-chain.md +++ b/specs/capella/beacon-chain.md @@ -43,6 +43,7 @@ - [Modified `process_execution_payload`](#modified-process_execution_payload) - [Modified `process_operations`](#modified-process_operations) - [New `process_bls_to_execution_change`](#new-process_bls_to_execution_change) +- [Testing](#testing) @@ -489,3 +490,59 @@ def process_bls_to_execution_change(state: BeaconState, + address_change.to_execution_address ) ``` + +## Testing + +*Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Capella testing only. +Modifications include: +1. Use `CAPELLA_FORK_VERSION` as the current fork version. +2. Utilize the Capella `BeaconBlockBody` when constructing the initial `latest_block_header`. + +```python +def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32, + eth1_timestamp: uint64, + deposits: Sequence[Deposit], + execution_payload_header: ExecutionPayloadHeader=ExecutionPayloadHeader() + ) -> BeaconState: + fork = Fork( + previous_version=CAPELLA_FORK_VERSION, # [Modified in Capella] for testing only + current_version=CAPELLA_FORK_VERSION, # [Modified in Capella] + epoch=GENESIS_EPOCH, + ) + state = BeaconState( + genesis_time=eth1_timestamp + GENESIS_DELAY, + fork=fork, + eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=uint64(len(deposits))), + latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), + randao_mixes=[eth1_block_hash] * EPOCHS_PER_HISTORICAL_VECTOR, # Seed RANDAO with Eth1 entropy + ) + + # Process deposits + leaves = list(map(lambda deposit: deposit.data, deposits)) + for index, deposit in enumerate(deposits): + deposit_data_list = List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:index + 1]) + state.eth1_data.deposit_root = hash_tree_root(deposit_data_list) + process_deposit(state, deposit) + + # Process activations + for index, validator in enumerate(state.validators): + balance = state.balances[index] + validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE) + if validator.effective_balance == MAX_EFFECTIVE_BALANCE: + validator.activation_eligibility_epoch = GENESIS_EPOCH + validator.activation_epoch = GENESIS_EPOCH + + # Set genesis validators root for domain separation and chain versioning + state.genesis_validators_root = hash_tree_root(state.validators) + + # Fill in sync committees + # Note: A duplicate committee is assigned for the current and next committee at genesis + state.current_sync_committee = get_next_sync_committee(state) + state.next_sync_committee = get_next_sync_committee(state) + + # 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/helpers/genesis.py b/tests/core/pyspec/eth2spec/test/helpers/genesis.py index 83994c409..e9ef66711 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/genesis.py +++ b/tests/core/pyspec/eth2spec/test/helpers/genesis.py @@ -1,5 +1,5 @@ from eth2spec.test.helpers.constants import ( - ALTAIR, BELLATRIX, + ALTAIR, BELLATRIX, CAPELLA, FORKS_BEFORE_ALTAIR, FORKS_BEFORE_BELLATRIX, FORKS_BEFORE_CAPELLA, ) from eth2spec.test.helpers.keys import pubkeys @@ -57,6 +57,9 @@ def create_genesis_state(spec, validator_balances, activation_threshold): elif spec.fork == BELLATRIX: previous_version = spec.config.ALTAIR_FORK_VERSION current_version = spec.config.BELLATRIX_FORK_VERSION + elif spec.fork == CAPELLA: + previous_version = spec.config.BELLATRIX_FORK_VERSION + current_version = spec.config.CAPELLA_FORK_VERSION state = spec.BeaconState( genesis_time=0, From 647e9d0ec0adf0acab687e7b6fb4f5be02ae7190 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 18 Jul 2022 14:45:00 +0800 Subject: [PATCH 2/2] PR feedback from @ralexstokes --- specs/altair/beacon-chain.md | 2 +- specs/bellatrix/beacon-chain.md | 2 +- specs/capella/beacon-chain.md | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/specs/altair/beacon-chain.md b/specs/altair/beacon-chain.md index a14ddb4f6..79ab8d022 100644 --- a/specs/altair/beacon-chain.md +++ b/specs/altair/beacon-chain.md @@ -682,7 +682,7 @@ def process_sync_committee_updates(state: BeaconState) -> None: This helper function is only for initializing the state for pure Altair testnets and tests. -*Note*: The function `initialize_beacon_state_from_eth1` is modified: (1) using `ALTAIR_FORK_VERSION` as the current fork version, (2) utilizing the Altair `BeaconBlockBody` when constructing the initial `latest_block_header`, and (3) adding initial sync committees. +*Note*: The function `initialize_beacon_state_from_eth1` is modified: (1) using `ALTAIR_FORK_VERSION` as the previous and current fork version, (2) utilizing the Altair `BeaconBlockBody` when constructing the initial `latest_block_header`, and (3) adding initial sync committees. ```python def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32, diff --git a/specs/bellatrix/beacon-chain.md b/specs/bellatrix/beacon-chain.md index b37a8ab71..983ecda23 100644 --- a/specs/bellatrix/beacon-chain.md +++ b/specs/bellatrix/beacon-chain.md @@ -399,7 +399,7 @@ def process_slashings(state: BeaconState) -> None: *Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Bellatrix testing only. Modifications include: -1. Use `BELLATRIX_FORK_VERSION` as the current fork version. +1. Use `BELLATRIX_FORK_VERSION` as the previous and current fork version. 2. Utilize the Bellatrix `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. diff --git a/specs/capella/beacon-chain.md b/specs/capella/beacon-chain.md index ca0305f04..06659349a 100644 --- a/specs/capella/beacon-chain.md +++ b/specs/capella/beacon-chain.md @@ -495,7 +495,7 @@ def process_bls_to_execution_change(state: BeaconState, *Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Capella testing only. Modifications include: -1. Use `CAPELLA_FORK_VERSION` as the current fork version. +1. Use `CAPELLA_FORK_VERSION` as the previous and current fork version. 2. Utilize the Capella `BeaconBlockBody` when constructing the initial `latest_block_header`. ```python @@ -541,7 +541,6 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32, state.next_sync_committee = get_next_sync_committee(state) # 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