Skip to content

Commit 95d25aa

Browse files
authored
Clean up genesis init helpers (#7713)
* Clean up genesis init helpers * create testnet/test genesis starting from phase0 and upgrade to the correct fork, like the spec suggests * reduce mem usage and number of copies while upgrading * add gloas to `ncli_testnet` generator * speed up mock deposit processing by skipping bls ops for most state creations and caching them for the others (attestation pool tests go from minutes to seconds) * consolidate the various ways to create deposits and states in the test suite to a single flow * make sure deposit creation uses the correct fork version in tests * fix main
1 parent 7d7bd3b commit 95d25aa

17 files changed

+252
-590
lines changed

beacon_chain/spec/beaconstate.nim

Lines changed: 40 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,7 +1930,7 @@ func compute_deposit_root(deposits: openArray[DepositData]): Eth2Digest =
19301930

19311931
mixInLength(merkleizer.getFinalHash(), deposits.len)
19321932

1933-
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#genesis
1933+
# https://github.com/ethereum/consensus-specs/blob/v1.6.0/specs/phase0/beacon-chain.md#genesis
19341934
proc initialize_beacon_state_from_eth1(
19351935
cfg: RuntimeConfig,
19361936
eth1_block_hash: Eth2Digest,
@@ -2027,123 +2027,6 @@ proc initialize_hashed_beacon_state_from_eth1*(
20272027
cfg, eth1_block_hash, eth1_timestamp, deposits, flags))
20282028
result.root = hash_tree_root(result.data)
20292029

2030-
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.8/specs/bellatrix/beacon-chain.md#testing
2031-
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#testing
2032-
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing
2033-
proc initialize_beacon_state_from_eth1*(
2034-
cfg: RuntimeConfig,
2035-
consensusFork: static ConsensusFork,
2036-
eth1_block_hash: Eth2Digest,
2037-
eth1_timestamp: uint64,
2038-
deposits: openArray[DepositData],
2039-
execution_payload_header: ForkyExecutionPayloadHeader,
2040-
flags: UpdateFlags = {}): consensusFork.BeaconState =
2041-
## Get the genesis ``BeaconState``.
2042-
##
2043-
## Before the beacon chain starts, validators will register in the Eth1 chain
2044-
## and deposit ETH. When enough many validators have registered, a
2045-
## `ChainStart` log will be emitted and the beacon chain can start beaconing.
2046-
##
2047-
## Because the state root hash is part of the genesis block, the beacon state
2048-
## must be calculated before creating the genesis block.
2049-
2050-
# Induct validators
2051-
# Not in spec: the system doesn't work unless there are at least SLOTS_PER_EPOCH
2052-
# validators - there needs to be at least one member in each committee -
2053-
# good to know for testing, though arguably the system is not that useful at
2054-
# at that point :)
2055-
doAssert deposits.lenu64 >= SLOTS_PER_EPOCH
2056-
2057-
let
2058-
forkVersion = cfg.forkVersion(consensusFork)
2059-
fork = Fork(
2060-
previous_version: forkVersion,
2061-
current_version: forkVersion,
2062-
epoch: GENESIS_EPOCH)
2063-
2064-
# TODO https://github.com/nim-lang/Nim/issues/19094
2065-
template state(): untyped = result
2066-
result = consensusFork.BeaconState(
2067-
fork: fork,
2068-
genesis_time: genesis_time_from_eth1_timestamp(cfg, eth1_timestamp),
2069-
eth1_data: Eth1Data(
2070-
deposit_count: deposits.lenu64,
2071-
deposit_root: compute_deposit_root(deposits),
2072-
block_hash: eth1_block_hash),
2073-
eth1_deposit_index: deposits.lenu64,
2074-
latest_block_header: BeaconBlockHeader(
2075-
body_root: hash_tree_root(default consensusFork.BeaconBlockBody)))
2076-
2077-
# Seed RANDAO with Eth1 entropy
2078-
state.randao_mixes.data.fill(eth1_block_hash)
2079-
2080-
var pubkeyToIndex = initTable[ValidatorPubKey, ValidatorIndex]()
2081-
for idx, deposit in deposits:
2082-
let
2083-
pubkey = deposit.pubkey
2084-
amount = deposit.amount
2085-
2086-
pubkeyToIndex.withValue(pubkey, foundIdx) do:
2087-
# Increase balance by deposit amount
2088-
increase_balance(state, foundIdx[], amount)
2089-
do:
2090-
if skipBlsValidation in flags or
2091-
verify_deposit_signature(cfg.GENESIS_FORK_VERSION, deposit):
2092-
pubkeyToIndex[pubkey] = ValidatorIndex(state.validators.len)
2093-
if not state.validators.add get_validator_from_deposit(
2094-
state, deposit.pubkey, deposit.withdrawal_credentials,
2095-
deposit.amount):
2096-
raiseAssert "too many validators"
2097-
if not state.balances.add(amount):
2098-
raiseAssert "same as validators"
2099-
2100-
else:
2101-
# Invalid deposits are perfectly possible
2102-
trace "Skipping deposit with invalid signature",
2103-
deposit = shortLog(deposit)
2104-
2105-
# Initialize epoch participations - TODO (This must be added to the spec)
2106-
var
2107-
empty_participation: EpochParticipationFlags
2108-
inactivity_scores = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]()
2109-
2110-
doAssert empty_participation.asList.setLen(state.validators.len)
2111-
doAssert inactivity_scores.data.setLen(state.validators.len)
2112-
inactivity_scores.resetCache()
2113-
2114-
state.previous_epoch_participation = empty_participation
2115-
state.current_epoch_participation = empty_participation
2116-
state.inactivity_scores = inactivity_scores
2117-
2118-
# Process activations
2119-
for vidx in state.validators.vindices:
2120-
let
2121-
balance = state.balances.item(vidx)
2122-
validator = addr state.validators.mitem(vidx)
2123-
2124-
validator.effective_balance = min(
2125-
balance - balance mod EFFECTIVE_BALANCE_INCREMENT.Gwei,
2126-
MAX_EFFECTIVE_BALANCE.Gwei)
2127-
2128-
if validator.effective_balance == MAX_EFFECTIVE_BALANCE.Gwei:
2129-
validator.activation_eligibility_epoch = GENESIS_EPOCH
2130-
validator.activation_epoch = GENESIS_EPOCH
2131-
2132-
# Set genesis validators root for domain separation and chain versioning
2133-
state.genesis_validators_root = hash_tree_root(state.validators)
2134-
2135-
# Fill in sync committees
2136-
# Note: A duplicate committee is assigned for the current and next committee at genesis
2137-
state.current_sync_committee = get_next_sync_committee(state)
2138-
state.next_sync_committee = get_next_sync_committee(state)
2139-
2140-
# [New in Bellatrix] Initialize the execution payload header
2141-
# If empty, will initialize a chain that has not yet gone through the Merge transition
2142-
state.latest_execution_payload_header = execution_payload_header
2143-
2144-
# TODO https://github.com/nim-lang/Nim/issues/19094
2145-
# state
2146-
21472030
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/altair/fork.md#upgrading-the-state
21482031
func translate_participation(
21492032
state: var altair.BeaconState,
@@ -2166,8 +2049,9 @@ func translate_participation(
21662049
state.previous_epoch_participation[index] =
21672050
add_flag(state.previous_epoch_participation.item(index), flag_index)
21682051

2169-
func upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState):
2170-
ref altair.BeaconState =
2052+
# upgrade_to_altair
2053+
func upgrade_to_next*(cfg: RuntimeConfig, pre: phase0.BeaconState, _: var StateCache):
2054+
altair.BeaconState =
21712055
var
21722056
empty_participation: EpochParticipationFlags
21732057
inactivity_scores = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]()
@@ -2177,7 +2061,8 @@ func upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState):
21772061
doAssert inactivity_scores.data.setLen(pre.validators.len)
21782062
inactivity_scores.resetCache()
21792063

2180-
let post = (ref altair.BeaconState)(
2064+
template post: untyped = result
2065+
post = altair.BeaconState(
21812066
genesis_time: pre.genesis_time,
21822067
genesis_validators_root: pre.genesis_validators_root,
21832068
slot: pre.slot,
@@ -2220,21 +2105,22 @@ func upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState):
22202105

22212106
# Fill in previous epoch participation from the pre state's pending
22222107
# attestations
2223-
translate_participation(post[], pre.previous_epoch_attestations.asSeq)
2108+
translate_participation(post, pre.previous_epoch_attestations.asSeq)
22242109

22252110
# Fill in sync committees
22262111
# Note: A duplicate committee is assigned for the current and next committee
22272112
# at the fork boundary
2228-
post[].current_sync_committee = get_next_sync_committee(post[])
2229-
post[].next_sync_committee = get_next_sync_committee(post[])
2113+
post.current_sync_committee = get_next_sync_committee(post)
2114+
post.next_sync_committee = get_next_sync_committee(post)
22302115

2231-
post
2116+
# result = post
22322117

22332118
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/bellatrix/fork.md#upgrading-the-state
2234-
func upgrade_to_bellatrix*(cfg: RuntimeConfig, pre: altair.BeaconState):
2235-
ref bellatrix.BeaconState =
2119+
# upgrade_to_bellatrix
2120+
func upgrade_to_next*(cfg: RuntimeConfig, pre: altair.BeaconState, _: var StateCache):
2121+
bellatrix.BeaconState =
22362122
let epoch = get_current_epoch(pre)
2237-
(ref bellatrix.BeaconState)(
2123+
bellatrix.BeaconState(
22382124
# Versioning
22392125
genesis_time: pre.genesis_time,
22402126
genesis_validators_root: pre.genesis_validators_root,
@@ -2288,8 +2174,9 @@ func upgrade_to_bellatrix*(cfg: RuntimeConfig, pre: altair.BeaconState):
22882174
)
22892175

22902176
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/capella/fork.md#upgrading-the-state
2291-
func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState):
2292-
ref capella.BeaconState =
2177+
# upgrade_to_capella
2178+
func upgrade_to_next*(cfg: RuntimeConfig, pre: bellatrix.BeaconState, _: var StateCache):
2179+
capella.BeaconState =
22932180
let
22942181
epoch = get_current_epoch(pre)
22952182
latest_execution_payload_header = capella.ExecutionPayloadHeader(
@@ -2310,7 +2197,7 @@ func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState):
23102197
withdrawals_root: Eth2Digest() # [New in Capella]
23112198
)
23122199

2313-
(ref capella.BeaconState)(
2200+
capella.BeaconState(
23142201
# Versioning
23152202
genesis_time: pre.genesis_time,
23162203
genesis_validators_root: pre.genesis_validators_root,
@@ -2371,8 +2258,9 @@ func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState):
23712258
)
23722259

23732260
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-beta.3/specs/deneb/fork.md#upgrading-the-state
2374-
func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
2375-
ref deneb.BeaconState =
2261+
# upgrade_to_deneb
2262+
func upgrade_to_next*(cfg: RuntimeConfig, pre: capella.BeaconState, _: var StateCache):
2263+
deneb.BeaconState =
23762264
let
23772265
epoch = get_current_epoch(pre)
23782266
latest_execution_payload_header = deneb.ExecutionPayloadHeader(
@@ -2395,7 +2283,7 @@ func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
23952283
excess_blob_gas: 0 # [New in Deneb]
23962284
)
23972285

2398-
(ref deneb.BeaconState)(
2286+
deneb.BeaconState(
23992287
# Versioning
24002288
genesis_time: pre.genesis_time,
24012289
genesis_validators_root: pre.genesis_validators_root,
@@ -2456,9 +2344,10 @@ func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
24562344
)
24572345

24582346
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.8/specs/electra/fork.md#upgrading-the-state
2459-
func upgrade_to_electra*(
2347+
# upgrade_to_electra
2348+
func upgrade_to_next*(
24602349
cfg: RuntimeConfig, pre: deneb.BeaconState, cache: var StateCache):
2461-
ref electra.BeaconState =
2350+
electra.BeaconState =
24622351
let epoch = get_current_epoch(pre)
24632352

24642353
var earliest_exit_epoch =
@@ -2469,7 +2358,8 @@ func upgrade_to_electra*(
24692358
earliest_exit_epoch = v.exit_epoch
24702359
earliest_exit_epoch += 1
24712360

2472-
let post = (ref electra.BeaconState)(
2361+
template post: untyped = result
2362+
post = electra.BeaconState(
24732363
# Versioning
24742364
genesis_time: pre.genesis_time,
24752365
genesis_validators_root: pre.genesis_validators_root,
@@ -2544,9 +2434,9 @@ func upgrade_to_electra*(
25442434
)
25452435

25462436
post.exit_balance_to_consume =
2547-
get_activation_exit_churn_limit(cfg, post[], cache)
2437+
get_activation_exit_churn_limit(cfg, post, cache)
25482438
post.consolidation_balance_to_consume =
2549-
get_consolidation_churn_limit(cfg, post[], cache)
2439+
get_consolidation_churn_limit(cfg, post, cache)
25502440

25512441
# [New in Electra:EIP7251]
25522442
# add validators that are not yet active to pending balance deposits
@@ -2574,18 +2464,19 @@ func upgrade_to_electra*(
25742464
# Ensure early adopters of compounding credentials go through the activation
25752465
# churn
25762466
for index, validator in post.validators:
2577-
if has_compounding_withdrawal_credential(type(post[]).kind, validator):
2578-
queue_excess_active_balance(post[], index.uint64)
2467+
if has_compounding_withdrawal_credential(type(post).kind, validator):
2468+
queue_excess_active_balance(post, index.uint64)
25792469

2580-
post
2470+
# result = post
25812471

25822472
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-alpha.6/specs/fulu/fork.md#upgrading-the-state
2583-
func upgrade_to_fulu*(
2473+
# upgrade_to_fulu
2474+
func upgrade_to_next*(
25842475
cfg: RuntimeConfig, pre: electra.BeaconState, cache: var StateCache):
2585-
ref fulu.BeaconState =
2476+
fulu.BeaconState =
25862477
let epoch = get_current_epoch(pre)
25872478

2588-
let post = (ref fulu.BeaconState)(
2479+
fulu.BeaconState(
25892480
# Versioning
25902481
genesis_time: pre.genesis_time,
25912482
genesis_validators_root: pre.genesis_validators_root,
@@ -2659,11 +2550,10 @@ func upgrade_to_fulu*(
26592550
proposer_lookahead: initialize_proposer_lookahead(pre, cache)
26602551
)
26612552

2662-
post
2663-
26642553
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.0/specs/gloas/fork.md#upgrading-the-state
2665-
func upgrade_to_gloas*(
2666-
cfg: RuntimeConfig, pre: fulu.BeaconState): ref gloas.BeaconState =
2554+
# upgrade_to_gloas
2555+
func upgrade_to_next*(
2556+
cfg: RuntimeConfig, pre: fulu.BeaconState, _: var StateCache): gloas.BeaconState =
26672557
let epoch = get_current_epoch(pre)
26682558

26692559
const full_execution_payload_availability = block:
@@ -2672,7 +2562,7 @@ func upgrade_to_gloas*(
26722562
setBit(res, i)
26732563
res
26742564

2675-
let post = (ref gloas.BeaconState)(
2565+
gloas.BeaconState(
26762566
# Versioning
26772567
genesis_time: pre.genesis_time,
26782568
genesis_validators_root: pre.genesis_validators_root,
@@ -2744,8 +2634,6 @@ func upgrade_to_gloas*(
27442634
latest_block_hash: pre.latest_execution_payload_header.block_hash
27452635
)
27462636

2747-
post
2748-
27492637
func latest_block_root*(state: ForkyBeaconState, state_root: Eth2Digest):
27502638
Eth2Digest =
27512639
# The root of the last block that was successfully applied to this state -

beacon_chain/spec/forks.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ template forky*(
10371037
elif kind == ConsensusFork.Phase0:
10381038
x.phase0Data
10391039
else:
1040-
{.error: "Unreachable".}
1040+
{.error: "Unreachable: " & $kind.}
10411041

10421042
template withEpochInfo*(x: ForkedEpochInfo, body: untyped): untyped =
10431043
case x.kind

beacon_chain/spec/signatures.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func get_deposit_signature*(genesis_fork_version: Version,
195195
func get_deposit_signature*(genesis_fork_version: Version,
196196
deposit: DepositData,
197197
privkey: ValidatorPrivKey): CookedSig =
198-
get_deposit_signature(genesis_fork_version, deposit.getDepositMessage(), privKey)
198+
get_deposit_signature(genesis_fork_version, deposit.getDepositMessage(), privkey)
199199

200200
proc verify_deposit_signature(genesis_fork_version: Version,
201201
deposit: DepositData,

0 commit comments

Comments
 (0)