add rest of EF consensus spec test Electra epoch transition fixture(s) (#6232)

This commit is contained in:
tersec 2024-04-24 12:28:47 +00:00 committed by GitHub
parent 9ba6b8d8a7
commit f53271eaaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 375 additions and 32 deletions

View File

@ -2465,11 +2465,44 @@ OK: 10/10 Fail: 0/10 Skip: 0/10
+ Participation flag updates - random_genesis [Preset: mainnet] OK
```
OK: 10/10 Fail: 0/10 Skip: 0/10
## EF - Electra - Epoch Processing - Pending balance deposits [Preset: mainnet]
```diff
+ Pending balance deposits - multiple_pending_deposits_above_churn [Preset: mainnet] OK
+ Pending balance deposits - multiple_pending_deposits_below_churn [Preset: mainnet] OK
+ Pending balance deposits - pending_deposit_balance_above_churn [Preset: mainnet] OK
+ Pending balance deposits - pending_deposit_balance_equal_churn [Preset: mainnet] OK
+ Pending balance deposits - pending_deposit_min_activation_balance [Preset: mainnet] OK
+ Pending balance deposits - pending_deposit_preexisting_churn [Preset: mainnet] OK
```
OK: 6/6 Fail: 0/6 Skip: 0/6
## EF - Electra - Epoch Processing - Pending consolidations [Preset: mainnet]
```diff
+ Pending consolidations - all_consolidation_cases_together [Preset: mainnet] OK
+ Pending consolidations - basic_pending_consolidation [Preset: mainnet] OK
+ Pending consolidations - consolidation_not_yet_withdrawable_validator [Preset: mainnet] OK
+ Pending consolidations - skip_consolidation_when_source_slashed [Preset: mainnet] OK
```
OK: 4/4 Fail: 0/4 Skip: 0/4
## EF - Electra - Epoch Processing - RANDAO mixes reset [Preset: mainnet]
```diff
+ RANDAO mixes reset - updated_randao_mixes [Preset: mainnet] OK
```
OK: 1/1 Fail: 0/1 Skip: 0/1
## EF - Electra - Epoch Processing - Registry updates [Preset: mainnet]
```diff
+ Registry updates - activation_queue_activation_and_ejection__1 [Preset: mainnet] OK
+ Registry updates - activation_queue_activation_and_ejection__churn_limit [Preset: mainnet] OK
+ Registry updates - activation_queue_activation_and_ejection__exceed_churn_limit [Preset: m OK
+ Registry updates - activation_queue_efficiency_min [Preset: mainnet] OK
+ Registry updates - activation_queue_no_activation_no_finality [Preset: mainnet] OK
+ Registry updates - activation_queue_sorting [Preset: mainnet] OK
+ Registry updates - activation_queue_to_activated_if_finalized [Preset: mainnet] OK
+ Registry updates - add_to_activation_queue [Preset: mainnet] OK
+ Registry updates - ejection [Preset: mainnet] OK
+ Registry updates - ejection_past_churn_limit_min [Preset: mainnet] OK
+ Registry updates - invalid_large_withdrawable_epoch [Preset: mainnet] OK
```
OK: 11/11 Fail: 0/11 Skip: 0/11
## EF - Electra - Epoch Processing - Rewards and penalties [Preset: mainnet]
```diff
+ Rewards and penalties - almost_empty_attestations [Preset: mainnet] OK
@ -3250,4 +3283,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88
OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL---
OK: 2601/2620 Fail: 0/2620 Skip: 19/2620
OK: 2622/2641 Fail: 0/2641 Skip: 19/2641

View File

@ -2576,11 +2576,51 @@ OK: 10/10 Fail: 0/10 Skip: 0/10
+ Participation flag updates - slightly_larger_random [Preset: minimal] OK
```
OK: 12/12 Fail: 0/12 Skip: 0/12
## EF - Electra - Epoch Processing - Pending balance deposits [Preset: minimal]
```diff
+ Pending balance deposits - multiple_pending_deposits_above_churn [Preset: minimal] OK
+ Pending balance deposits - multiple_pending_deposits_below_churn [Preset: minimal] OK
+ Pending balance deposits - pending_deposit_balance_above_churn [Preset: minimal] OK
+ Pending balance deposits - pending_deposit_balance_equal_churn [Preset: minimal] OK
+ Pending balance deposits - pending_deposit_min_activation_balance [Preset: minimal] OK
+ Pending balance deposits - pending_deposit_preexisting_churn [Preset: minimal] OK
```
OK: 6/6 Fail: 0/6 Skip: 0/6
## EF - Electra - Epoch Processing - Pending consolidations [Preset: minimal]
```diff
+ Pending consolidations - all_consolidation_cases_together [Preset: minimal] OK
+ Pending consolidations - basic_pending_consolidation [Preset: minimal] OK
+ Pending consolidations - consolidation_not_yet_withdrawable_validator [Preset: minimal] OK
+ Pending consolidations - skip_consolidation_when_source_slashed [Preset: minimal] OK
```
OK: 4/4 Fail: 0/4 Skip: 0/4
## EF - Electra - Epoch Processing - RANDAO mixes reset [Preset: minimal]
```diff
+ RANDAO mixes reset - updated_randao_mixes [Preset: minimal] OK
```
OK: 1/1 Fail: 0/1 Skip: 0/1
## EF - Electra - Epoch Processing - Registry updates [Preset: minimal]
```diff
+ Registry updates - activation_churn_limit__equal_to_activation_limit [Preset: minimal] OK
+ Registry updates - activation_churn_limit__greater_than_activation_limit [Preset: minimal] OK
+ Registry updates - activation_churn_limit__less_than_activation_limit [Preset: minimal] OK
+ Registry updates - activation_queue_activation_and_ejection__1 [Preset: minimal] OK
+ Registry updates - activation_queue_activation_and_ejection__churn_limit [Preset: minimal] OK
+ Registry updates - activation_queue_activation_and_ejection__exceed_churn_limit [Preset: m OK
+ Registry updates - activation_queue_activation_and_ejection__exceed_scaled_churn_limit [Pr OK
+ Registry updates - activation_queue_activation_and_ejection__scaled_churn_limit [Preset: m OK
+ Registry updates - activation_queue_efficiency_min [Preset: minimal] OK
+ Registry updates - activation_queue_efficiency_scaled [Preset: minimal] OK
+ Registry updates - activation_queue_no_activation_no_finality [Preset: minimal] OK
+ Registry updates - activation_queue_sorting [Preset: minimal] OK
+ Registry updates - activation_queue_to_activated_if_finalized [Preset: minimal] OK
+ Registry updates - add_to_activation_queue [Preset: minimal] OK
+ Registry updates - ejection [Preset: minimal] OK
+ Registry updates - ejection_past_churn_limit_min [Preset: minimal] OK
+ Registry updates - ejection_past_churn_limit_scaled [Preset: minimal] OK
+ Registry updates - invalid_large_withdrawable_epoch [Preset: minimal] OK
```
OK: 18/18 Fail: 0/18 Skip: 0/18
## EF - Electra - Epoch Processing - Rewards and penalties [Preset: minimal]
```diff
+ Rewards and penalties - almost_empty_attestations [Preset: minimal] OK
@ -3530,4 +3570,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207
OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL---
OK: 2850/2872 Fail: 0/2872 Skip: 22/2872
OK: 2878/2900 Fail: 0/2900 Skip: 22/2900

View File

@ -91,7 +91,9 @@ func get_validator_activation_churn_limit*(
get_validator_churn_limit(cfg, state, cache))
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#initiate_validator_exit
func get_state_exit_queue_info*(state: ForkyBeaconState): ExitQueueInfo =
func get_state_exit_queue_info*(
state: phase0.BeaconState | altair.BeaconState | bellatrix.BeaconState |
capella.BeaconState | deneb.BeaconState): ExitQueueInfo =
var
exit_queue_epoch = compute_activation_exit_epoch(get_current_epoch(state))
exit_queue_churn: uint64
@ -118,11 +120,19 @@ func get_state_exit_queue_info*(state: ForkyBeaconState): ExitQueueInfo =
ExitQueueInfo(
exit_queue_epoch: exit_queue_epoch, exit_queue_churn: exit_queue_churn)
func get_state_exit_queue_info*(state: electra.BeaconState): ExitQueueInfo =
# Electra initiate_validator_exit doesn't have same quadratic aspect given
# StateCache balance caching
default(ExitQueueInfo)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#initiate_validator_exit
func initiate_validator_exit*(
cfg: RuntimeConfig, state: var ForkyBeaconState,
index: ValidatorIndex, exit_queue_info: ExitQueueInfo, cache: var StateCache):
Result[ExitQueueInfo, cstring] =
cfg: RuntimeConfig,
state: var (phase0.BeaconState | altair.BeaconState |
bellatrix.BeaconState | capella.BeaconState |
deneb.BeaconState),
index: ValidatorIndex, exit_queue_info: ExitQueueInfo,
cache: var StateCache): Result[ExitQueueInfo, cstring] =
## Initiate the exit of the validator with index ``index``.
if state.validators.item(index).exit_epoch != FAR_FUTURE_EPOCH:
@ -156,6 +166,85 @@ func initiate_validator_exit*(
ok(ExitQueueInfo(
exit_queue_epoch: exit_queue_epoch, exit_queue_churn: exit_queue_churn))
func get_total_active_balance*(state: ForkyBeaconState, cache: var StateCache): Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_balance_churn_limit
func get_balance_churn_limit(
cfg: RuntimeConfig, state: electra.BeaconState,
cache: var StateCache): Gwei =
## Return the churn limit for the current epoch.
let churn = max(
cfg.MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA.Gwei,
get_total_active_balance(state, cache) div cfg.CHURN_LIMIT_QUOTIENT
)
churn - churn mod EFFECTIVE_BALANCE_INCREMENT.Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_activation_exit_churn_limit
func get_activation_exit_churn_limit*(
cfg: RuntimeConfig, state: electra.BeaconState, cache: var StateCache):
Gwei =
## Return the churn limit for the current epoch dedicated to activations and
## exits.
min(
cfg.MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT.Gwei,
get_balance_churn_limit(cfg, state, cache))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-compute_exit_epoch_and_update_churn
func compute_exit_epoch_and_update_churn(
cfg: RuntimeConfig, state: var electra.BeaconState, exit_balance: Gwei,
cache: var StateCache): Epoch =
var earliest_exit_epoch = max(state.earliest_exit_epoch,
compute_activation_exit_epoch(get_current_epoch(state)))
let per_epoch_churn = get_activation_exit_churn_limit(cfg, state, cache)
# New epoch for exits.
var exit_balance_to_consume =
if state.earliest_exit_epoch < earliest_exit_epoch:
per_epoch_churn
else:
state.exit_balance_to_consume
# Exit doesn't fit in the current earliest epoch.
if exit_balance > exit_balance_to_consume:
let
balance_to_process = exit_balance - exit_balance_to_consume
additional_epochs = (balance_to_process - 1.Gwei) div per_epoch_churn + 1
earliest_exit_epoch += additional_epochs
exit_balance_to_consume += additional_epochs * per_epoch_churn
# Consume the balance and update state variables.
state.exit_balance_to_consume = exit_balance_to_consume - exit_balance
state.earliest_exit_epoch = earliest_exit_epoch
state.earliest_exit_epoch
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated--initiate_validator_exit
func initiate_validator_exit*(
cfg: RuntimeConfig, state: var electra.BeaconState,
index: ValidatorIndex, exit_queue_info: ExitQueueInfo,
cache: var StateCache): Result[ExitQueueInfo, cstring] =
## Initiate the exit of the validator with index ``index``.
# Return if validator already initiated exit
var validator = state.validators.item(index)
if validator.exit_epoch != FAR_FUTURE_EPOCH:
return
# Compute exit queue epoch [Modified in Electra:EIP7251]
let exit_queue_epoch = compute_exit_epoch_and_update_churn(
cfg, state, validator.effective_balance, cache)
# Set validator exit epoch and withdrawable epoch
validator.exit_epoch = exit_queue_epoch
validator.withdrawable_epoch =
Epoch(validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
if validator.withdrawable_epoch < validator.exit_epoch:
return err("Invalid large withdrawable epoch")
state.validators.mitem(index) = validator
# The Electra initiate_validator_exit() isn't accidentally quadratic; ignore
ok(static(default(ExitQueueInfo)))
from ./datatypes/deneb import BeaconState
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator
@ -304,7 +393,8 @@ func get_initial_beacon_block*(state: deneb.HashedBeaconState):
deneb.TrustedSignedBeaconBlock(
message: message, root: hash_tree_root(message))
from ./datatypes/electra import HashedBeaconState, TrustedSignedBeaconBlock
from ./datatypes/electra import
HashedBeaconState, PendingBalanceDeposit, TrustedSignedBeaconBlock
# TODO spec link here when it exists
func get_initial_beacon_block*(state: electra.HashedBeaconState):
@ -897,6 +987,41 @@ func has_execution_withdrawal_credential(validator: Validator): bool =
has_compounding_withdrawal_credential(validator) or
has_eth1_withdrawal_credential(validator)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#get_validator_max_effective_balance
func get_validator_max_effective_balance(validator: Validator): Gwei =
## Get max effective balance for ``validator``.
if has_compounding_withdrawal_credential(validator):
MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei
else:
MIN_ACTIVATION_BALANCE.Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_active_balance
func get_active_balance*(
state: electra.BeaconState, validator_index: ValidatorIndex): Gwei =
let max_effective_balance =
get_validator_max_effective_balance(state.validators[validator_index])
min(state.balances[validator_index], max_effective_balance)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-queue_excess_active_balance
func queue_excess_active_balance(
state: var electra.BeaconState, index: ValidatorIndex) =
let balance = state.balances.item(index)
if balance > MIN_ACTIVATION_BALANCE.Gwei:
let excess_balance = balance - MIN_ACTIVATION_BALANCE.Gwei
state.balances.mitem(index) = MIN_ACTIVATION_BALANCE.Gwei
debugRaiseAssert "maybe check return value"
discard state.pending_balance_deposits.add(
PendingBalanceDeposit(index: index.uint64, amount: excess_balance)
)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-switch_to_compounding_validator
func switch_to_compounding_validator*(
state: var electra.BeaconState, index: ValidatorIndex) =
let validator = addr state.validators.mitem(index)
if has_eth1_withdrawal_credential(validator[]):
validator.withdrawal_credentials.data[0] = COMPOUNDING_WITHDRAWAL_PREFIX
queue_excess_active_balance(state, index)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-get_expected_withdrawals
func get_expected_withdrawals*(
state: capella.BeaconState | deneb.BeaconState | electra.BeaconState):

View File

@ -77,6 +77,8 @@ type
MIN_PER_EPOCH_CHURN_LIMIT*: uint64
CHURN_LIMIT_QUOTIENT*: uint64
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT*: uint64
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA*: uint64
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT*: uint64
# Fork choice
# TODO PROPOSER_SCORE_BOOST*: uint64
@ -151,8 +153,6 @@ when const_preset == "mainnet":
# Free-form short name of the network that this configuration applies to - known
# canonical network names include:
# * 'mainnet' - there can be only one
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
@ -228,6 +228,10 @@ when const_preset == "mainnet":
CHURN_LIMIT_QUOTIENT: 65536,
# [New in Deneb:EIP7514] 2**3 (= 8)
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8,
# [New in Electra:EIP7251] 2**7 * 10**9 (= 128,000,000,000)
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000'u64,
# [New in Electra:EIP7251] 2**8 * 10**9 (= 256,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000'u64,
# Deposit contract
# ---------------------------------------------------------------
@ -298,8 +302,6 @@ elif const_preset == "gnosis":
# Free-form short name of the network that this configuration applies to - known
# canonical network names include:
# * 'mainnet' - there can be only one
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
@ -376,6 +378,10 @@ elif const_preset == "gnosis":
CHURN_LIMIT_QUOTIENT: 4096,
# [New in Deneb:EIP7514] 2**3 (= 8)
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8,
# [New in Electra:EIP7251] 2**7 * 10**9 (= 128,000,000,000) (copied from EF mainnet)
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000'u64,
# [New in Electra:EIP7251] 2**8 * 10**9 (= 256,000,000,000) (copied from EF mainnet)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000'u64,
# Deposit contract
# ---------------------------------------------------------------
@ -440,8 +446,6 @@ elif const_preset == "minimal":
# Free-form short name of the network that this configuration applies to - known
# canonical network names include:
# * 'mainnet' - there can be only one
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
@ -519,6 +523,10 @@ elif const_preset == "minimal":
CHURN_LIMIT_QUOTIENT: 32,
# [New in Deneb:EIP7514] [customized]
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4,
# [New in Electra:EIP7251] 2**6 * 10**9 (= 64,000,000,000)
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000'u64,
# [New in Electra:EIP7251] 2**7 * 10**9 (= 128,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000'u64,
# Deposit contract

View File

@ -867,19 +867,13 @@ from std/heapqueue import HeapQueue, `[]`, len, push, replace
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#registry-updates
func process_registry_updates*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cache: var StateCache):
Result[void, cstring] =
cfg: RuntimeConfig,
state: var (phase0.BeaconState | altair.BeaconState |
bellatrix.BeaconState | capella.BeaconState |
deneb.BeaconState),
cache: var StateCache): Result[void, cstring] =
## Process activation eligibility and ejections
# Make visible, e.g.,
# https://github.com/status-im/nimbus-eth2/pull/608
# https://github.com/sigp/lighthouse/pull/657
let epoch {.used.} = get_current_epoch(state)
trace "process_registry_updates validator balances",
balances=state.balances,
active_validator_indices=get_active_validator_indices(state, epoch),
epoch=epoch
# is_active_validator(...) is activation_epoch <= epoch < exit_epoch,
# and changes here to either activation_epoch or exit_epoch only take
# effect with a compute_activation_exit_epoch(...) delay of, based on
@ -939,6 +933,32 @@ func process_registry_updates*(
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated--process_registry_updates
func process_registry_updates*(
cfg: RuntimeConfig, state: var electra.BeaconState, cache: var StateCache):
Result[void, cstring] =
# Process activation eligibility and ejections
for index in 0 ..< state.validators.len:
let validator = state.validators.item(index)
if is_eligible_for_activation_queue(validator):
# Usually not too many at once, so do this individually
state.validators.mitem(index).activation_eligibility_epoch =
get_current_epoch(state) + 1
if is_active_validator(validator, get_current_epoch(state)) and
distinctBase(validator.effective_balance) <= cfg.EJECTION_BALANCE:
discard ? initiate_validator_exit(
cfg, state, ValidatorIndex(index), static(default(ExitQueueInfo)), cache)
# Activate all eligible validators
let activation_epoch =
compute_activation_exit_epoch(get_current_epoch(state))
for index in 0 ..< state.validators.len:
if is_eligible_for_activation(state, state.validators.item(index)):
state.validators.mitem(index).activation_epoch = activation_epoch
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/bellatrix/beacon-chain.md#slashings
@ -1166,6 +1186,66 @@ func process_historical_summaries_update*(
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_balance_deposits
func process_pending_balance_deposits*(
cfg: RuntimeConfig, state: var electra.BeaconState,
cache: var StateCache) =
let
available_for_processing = state.deposit_balance_to_consume +
get_activation_exit_churn_limit(cfg, state, cache)
var
processed_amount = 0.Gwei
next_deposit_index = 0.Gwei
for deposit in state.pending_balance_deposits:
if processed_amount + deposit.amount > available_for_processing:
break
debugRaiseAssert "do this validatorindex check properly (it truncates)"
increase_balance(state, deposit.index.ValidatorIndex, deposit.amount)
processed_amount += deposit.amount
inc next_deposit_index
state.pending_balance_deposits =
HashList[PendingBalanceDeposit, Limit PENDING_BALANCE_DEPOSITS_LIMIT].init(
state.pending_balance_deposits.asSeq[next_deposit_index..^1])
if len(state.pending_balance_deposits) == 0:
state.deposit_balance_to_consume = Gwei(0)
else:
state.deposit_balance_to_consume =
available_for_processing - processed_amount
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_consolidations
func process_pending_consolidations*(cfg: RuntimeConfig, state: var electra.BeaconState) =
var next_pending_consolidation = 0
for pending_consolidation in state.pending_consolidations:
let source_validator =
state.validators.item(pending_consolidation.source_index)
if source_validator.slashed:
next_pending_consolidation += 1
continue
if source_validator.withdrawable_epoch > get_current_epoch(state):
break
# Churn any target excess active balance of target and raise its max
debugRaiseAssert "truncating integer conversion"
switch_to_compounding_validator(
state, pending_consolidation.target_index.ValidatorIndex)
# Move active balance to target. Excess balance is withdrawable.
debugRaiseAssert "Truncating"
let active_balance = get_active_balance(
state, pending_consolidation.source_index.ValidatorIndex)
decrease_balance(
state, pending_consolidation.source_index.ValidatorIndex, active_balance)
increase_balance(
state, pending_consolidation.target_index.ValidatorIndex, active_balance)
inc next_pending_consolidation
state.pending_consolidations =
HashList[PendingConsolidation, Limit PENDING_CONSOLIDATIONS_LIMIT].init(
state.pending_consolidations.asSeq[next_pending_consolidation..^1])
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#epoch-processing
proc process_epoch*(
cfg: RuntimeConfig, state: var phase0.BeaconState, flags: UpdateFlags,
@ -1273,7 +1353,52 @@ proc process_epoch*(
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#epoch-processing
proc process_epoch*(
cfg: RuntimeConfig,
state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState),
state: var (capella.BeaconState | deneb.BeaconState),
flags: UpdateFlags, cache: var StateCache, info: var altair.EpochInfo):
Result[void, cstring] =
let epoch = get_current_epoch(state)
trace "process_epoch", epoch
info.init(state)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#justification-and-finalization
process_justification_and_finalization(state, info.balances, flags)
# state.slot hasn't been incremented yet.
if strictVerification in flags:
# Rule 2/3/4 finalization results in the most pessimal case. The other
# three finalization rules finalize more quickly as long as the any of
# the finalization rules triggered.
if (epoch >= 2 and state.current_justified_checkpoint.epoch + 2 < epoch) or
(epoch >= 3 and state.finalized_checkpoint.epoch + 3 < epoch):
fatal "The network did not finalize",
epoch, finalizedEpoch = state.finalized_checkpoint.epoch
quit 1
process_inactivity_updates(cfg, state, info)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#rewards-and-penalties
process_rewards_and_penalties(cfg, state, info)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#registry-updates
? process_registry_updates(cfg, state, cache)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings
process_slashings(state, info.balances.current_epoch)
process_eth1_data_reset(state)
process_effective_balance_updates(state)
process_slashings_reset(state)
process_randao_mixes_reset(state)
? process_historical_summaries_update(state) # [Modified in Capella]
process_participation_flag_updates(state)
process_sync_committee_updates(state)
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#epoch-processing
proc process_epoch*(
cfg: RuntimeConfig, state: var electra.BeaconState,
flags: UpdateFlags, cache: var StateCache, info: var altair.EpochInfo):
Result[void, cstring] =
let epoch = get_current_epoch(state)

View File

@ -38,15 +38,17 @@ const
SyncCommitteeDir = RootDir/"sync_committee_updates"
RewardsAndPenaltiesDir = RootDir/"rewards_and_penalties"
HistoricalSummariesUpdateDir = RootDir/"historical_summaries_update"
PendingBalanceDepositsDir = RootDir/"pending_balance_deposits"
PendingConsolidationsDir = RootDir/"pending_consolidations"
debugRaiseAssert "check Electra state transition epoch subdirectories"
doAssert true or (toHashSet(mapIt(toSeq(walkDir(RootDir, relative = false)), it.path)) -
doAssert (toHashSet(mapIt(toSeq(walkDir(RootDir, relative = false)), it.path)) -
toHashSet([SyncCommitteeDir])) ==
toHashSet([
JustificationFinalizationDir, InactivityDir, RegistryUpdatesDir,
SlashingsDir, Eth1DataResetDir, EffectiveBalanceUpdatesDir,
SlashingsResetDir, RandaoMixesResetDir, ParticipationFlagDir,
RewardsAndPenaltiesDir, HistoricalSummariesUpdateDir])
RewardsAndPenaltiesDir, HistoricalSummariesUpdateDir,
PendingBalanceDepositsDir, PendingConsolidationsDir])
template runSuite(
suiteDir, testName: string, transitionProc: untyped): untyped =
@ -95,10 +97,8 @@ runSuite(RewardsAndPenaltiesDir, "Rewards and penalties"):
# Registry updates
# ---------------------------------------------------------------
when false:
debugRaiseAssert "re-enable registry updates tests in Electra state transition epoch checks"
runSuite(RegistryUpdatesDir, "Registry updates"):
process_registry_updates(cfg, state, cache)
runSuite(RegistryUpdatesDir, "Registry updates"):
process_registry_updates(cfg, state, cache)
# Slashings
# ---------------------------------------------------------------
@ -142,6 +142,18 @@ runSuite(ParticipationFlagDir, "Participation flag updates"):
process_participation_flag_updates(state)
Result[void, cstring].ok()
# Pending balance deposits
# ---------------------------------------------------------------
runSuite(PendingBalanceDepositsDir, "Pending balance deposits"):
process_pending_balance_deposits(cfg, state, cache)
Result[void, cstring].ok()
# Pending consolidations
# ---------------------------------------------------------------
runSuite(PendingConsolidationsDir, "Pending consolidations"):
process_pending_consolidations(cfg, state)
Result[void, cstring].ok()
# Sync committee updates
# ---------------------------------------------------------------