mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-01-24 01:20:56 +00:00
Merge pull request #2323 from ethereum/prepare_state
Simplify Altair "genesis"
This commit is contained in:
commit
2628721f96
@ -52,6 +52,7 @@
|
||||
- [Slashings](#slashings)
|
||||
- [Participation flags updates](#participation-flags-updates)
|
||||
- [Sync committee updates](#sync-committee-updates)
|
||||
- [Initialize state for pure Altair testnets and test vectors](#initialize-state-for-pure-altair-testnets-and-test-vectors)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
@ -661,3 +662,51 @@ def process_sync_committee_updates(state: BeaconState) -> None:
|
||||
state.current_sync_committee = state.next_sync_committee
|
||||
state.next_sync_committee = get_sync_committee(state, next_epoch + EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
|
||||
```
|
||||
|
||||
## Initialize state for pure Altair testnets and test vectors
|
||||
|
||||
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.
|
||||
|
||||
```python
|
||||
def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
|
||||
eth1_timestamp: uint64,
|
||||
deposits: Sequence[Deposit]) -> BeaconState:
|
||||
fork = Fork(
|
||||
previous_version=GENESIS_FORK_VERSION,
|
||||
current_version=ALTAIR_FORK_VERSION, # [Modified in Altair]
|
||||
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)
|
||||
|
||||
# [New in Altair] Fill in sync committees
|
||||
state.current_sync_committee = get_sync_committee(state, get_current_epoch(state))
|
||||
state.next_sync_committee = get_sync_committee(state, get_current_epoch(state) + EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
|
||||
|
||||
return state
|
||||
```
|
||||
|
@ -34,6 +34,8 @@ Warning: this configuration is not definitive.
|
||||
|
||||
TBD. Social consensus, along with state conditions such as epoch boundary, finality, deposits, active validator count, etc. may be part of the decision process to trigger the fork. For now we assume the condition will be triggered at epoch `ALTAIR_FORK_EPOCH`.
|
||||
|
||||
Note that for the pure Altair networks, we don't apply `upgrade_to_altair` since it starts with Altair version logic.
|
||||
|
||||
### Upgrading the state
|
||||
|
||||
After `process_slots` of Phase 0 finishes, if `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == ALTAIR_FORK_EPOCH`, an irregular state change is made to upgrade to Altair.
|
||||
|
@ -7,8 +7,8 @@ from eth2spec.utils import bls
|
||||
|
||||
from .exceptions import SkippedTest
|
||||
from .helpers.constants import (
|
||||
PHASE0, ALTAIR, MERGE, SHARDING, CUSTODY_GAME, DAS,
|
||||
ALL_PHASES,
|
||||
PHASE0, ALTAIR,
|
||||
ALL_PHASES, FORKS_BEFORE_ALTAIR,
|
||||
)
|
||||
from .helpers.genesis import create_genesis_state
|
||||
from .utils import vector_test, with_meta_tags
|
||||
@ -55,17 +55,11 @@ class SpecForks(TypedDict, total=False):
|
||||
|
||||
def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Callable[[Any], int],
|
||||
spec: Spec, phases: SpecForks):
|
||||
|
||||
p0 = phases[PHASE0]
|
||||
balances = balances_fn(p0)
|
||||
activation_threshold = threshold_fn(p0)
|
||||
|
||||
state = create_genesis_state(spec=p0, validator_balances=balances,
|
||||
phase = phases[spec.fork]
|
||||
balances = balances_fn(phase)
|
||||
activation_threshold = threshold_fn(phase)
|
||||
state = create_genesis_state(spec=phase, validator_balances=balances,
|
||||
activation_threshold=activation_threshold)
|
||||
# TODO: upgrade to merge spec, and later sharding.
|
||||
if spec.fork == ALTAIR:
|
||||
state = phases[ALTAIR].upgrade_to_altair(state)
|
||||
|
||||
return state
|
||||
|
||||
|
||||
@ -368,8 +362,6 @@ def with_configs(configs, reason=None):
|
||||
|
||||
|
||||
def is_post_altair(spec):
|
||||
# TODO: everything runs in parallel to Altair.
|
||||
# After features are rebased on the Altair fork, this can be reduced to just PHASE0.
|
||||
if spec.fork in [PHASE0, MERGE, SHARDING, CUSTODY_GAME, DAS]:
|
||||
if spec.fork in FORKS_BEFORE_ALTAIR:
|
||||
return False
|
||||
return True
|
||||
|
@ -18,7 +18,9 @@ DAS = SpecForkName('das')
|
||||
ALL_PHASES = (PHASE0, ALTAIR)
|
||||
# The forks that output to the test vectors.
|
||||
TESTGEN_FORKS = (PHASE0, ALTAIR)
|
||||
|
||||
# TODO: everything runs in parallel to Altair.
|
||||
# After features are rebased on the Altair fork, this can be reduced to just PHASE0.
|
||||
FORKS_BEFORE_ALTAIR = (PHASE0, MERGE, SHARDING, CUSTODY_GAME, DAS)
|
||||
|
||||
#
|
||||
# Config
|
||||
|
@ -1,7 +1,5 @@
|
||||
from eth_utils import encode_hex
|
||||
|
||||
from eth2spec.phase0 import spec as phase0_spec
|
||||
|
||||
|
||||
def get_anchor_root(spec, state):
|
||||
anchor_block_header = state.latest_block_header.copy()
|
||||
@ -58,8 +56,7 @@ def get_genesis_forkchoice_store(spec, genesis_state):
|
||||
|
||||
def get_genesis_forkchoice_store_and_block(spec, genesis_state):
|
||||
assert genesis_state.slot == spec.GENESIS_SLOT
|
||||
# The genesis block must be a Phase 0 `BeaconBlock`
|
||||
genesis_block = phase0_spec.BeaconBlock(state_root=genesis_state.hash_tree_root())
|
||||
genesis_block = spec.BeaconBlock(state_root=genesis_state.hash_tree_root())
|
||||
return spec.get_forkchoice_store(genesis_state, genesis_block), genesis_block
|
||||
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
from eth2spec.test.helpers.constants import (
|
||||
ALTAIR,
|
||||
FORKS_BEFORE_ALTAIR,
|
||||
)
|
||||
from eth2spec.test.helpers.keys import pubkeys
|
||||
|
||||
|
||||
@ -20,6 +24,11 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
||||
deposit_root = b'\x42' * 32
|
||||
|
||||
eth1_block_hash = b'\xda' * 32
|
||||
current_version = spec.GENESIS_FORK_VERSION
|
||||
|
||||
if spec.fork == ALTAIR:
|
||||
current_version = spec.ALTAIR_FORK_VERSION
|
||||
|
||||
state = spec.BeaconState(
|
||||
genesis_time=0,
|
||||
eth1_deposit_index=len(validator_balances),
|
||||
@ -30,7 +39,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
||||
),
|
||||
fork=spec.Fork(
|
||||
previous_version=spec.GENESIS_FORK_VERSION,
|
||||
current_version=spec.GENESIS_FORK_VERSION,
|
||||
current_version=current_version,
|
||||
epoch=spec.GENESIS_EPOCH,
|
||||
),
|
||||
latest_block_header=spec.BeaconBlockHeader(body_root=spec.hash_tree_root(spec.BeaconBlockBody())),
|
||||
@ -47,8 +56,19 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
||||
if validator.effective_balance >= activation_threshold:
|
||||
validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
|
||||
validator.activation_epoch = spec.GENESIS_EPOCH
|
||||
if spec.fork not in FORKS_BEFORE_ALTAIR:
|
||||
state.previous_epoch_participation.append(spec.ParticipationFlags(0b0000_0000))
|
||||
state.current_epoch_participation.append(spec.ParticipationFlags(0b0000_0000))
|
||||
state.inactivity_scores.append(spec.uint64(0))
|
||||
|
||||
# Set genesis validators root for domain separation and chain versioning
|
||||
state.genesis_validators_root = spec.hash_tree_root(state.validators)
|
||||
|
||||
if spec.fork not in FORKS_BEFORE_ALTAIR:
|
||||
# Fill in sync committees
|
||||
state.current_sync_committee = spec.get_sync_committee(state, spec.get_current_epoch(state))
|
||||
state.next_sync_committee = (
|
||||
spec.get_sync_committee(state, spec.get_current_epoch(state) + spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
|
||||
)
|
||||
|
||||
return state
|
||||
|
@ -139,6 +139,8 @@ E.g. `pre.ssz_snappy`, `deposit.ssz_snappy`, `post.ssz_snappy`.
|
||||
Diffing a `pre.ssz_snappy` and `post.ssz_snappy` provides all the information for testing, when decompressed and decoded.
|
||||
Then the difference between pre and post can be compared to anything that changes the pre state, e.g. `deposit.ssz_snappy`
|
||||
|
||||
Note that by default, the SSZ data is in the given test case's <fork or phase name> version, e.g., if it's `altair` test case, use `altair.BeaconState` container to deserialize the given state.
|
||||
|
||||
YAML is generally used for test metadata, and for tests that do not use SSZ: e.g. shuffling and BLS tests.
|
||||
In this case, there is no point in adding special SSZ types. And the size and efficiency of YAML is acceptable.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user