add EF consensus spec test Electra fork and transition fixtures (#6251)

This commit is contained in:
tersec 2024-04-28 14:13:17 +00:00 committed by GitHub
parent a66876c8e5
commit abc8bbbf23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 240 additions and 43 deletions

View File

@ -2546,6 +2546,22 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
+ [Valid] EF - Electra - Finality - finality_rule_4 [Preset: mainnet] OK
```
OK: 5/5 Fail: 0/5 Skip: 0/5
## EF - Electra - Fork [Preset: mainnet]
```diff
+ EF - Electra - Fork - electra_fork_random_0 [Preset: mainnet] OK
+ EF - Electra - Fork - electra_fork_random_1 [Preset: mainnet] OK
+ EF - Electra - Fork - electra_fork_random_2 [Preset: mainnet] OK
+ EF - Electra - Fork - electra_fork_random_3 [Preset: mainnet] OK
+ EF - Electra - Fork - electra_fork_random_low_balances [Preset: mainnet] OK
+ EF - Electra - Fork - electra_fork_random_misc_balances [Preset: mainnet] OK
+ EF - Electra - Fork - fork_base_state [Preset: mainnet] OK
+ EF - Electra - Fork - fork_many_next_epoch [Preset: mainnet] OK
+ EF - Electra - Fork - fork_next_epoch [Preset: mainnet] OK
+ EF - Electra - Fork - fork_next_epoch_with_block [Preset: mainnet] OK
+ EF - Electra - Fork - fork_random_low_balances [Preset: mainnet] OK
+ EF - Electra - Fork - fork_random_misc_balances [Preset: mainnet] OK
```
OK: 12/12 Fail: 0/12 Skip: 0/12
## EF - Electra - Operations - Attestation [Preset: mainnet]
```diff
+ [Invalid] EF - Electra - Operations - Attestation - invalid_after_max_inclusion_slot OK
@ -3114,6 +3130,35 @@ OK: 76/76 Fail: 0/76 Skip: 0/76
+ EF - Electra - Slots - slots_2 [Preset: mainnet] OK
```
OK: 6/6 Fail: 0/6 Skip: 0/6
## EF - Electra - Transition [Preset: mainnet]
```diff
+ EF - Electra - Transition - non_empty_historical_roots [Preset: mainnet] OK
+ EF - Electra - Transition - normal_transition [Preset: mainnet] OK
+ EF - Electra - Transition - simple_transition [Preset: mainnet] OK
+ EF - Electra - Transition - transition_attestation_from_previous_fork_with_new_range [Pres OK
+ EF - Electra - Transition - transition_missing_first_post_block [Preset: mainnet] OK
+ EF - Electra - Transition - transition_missing_last_pre_fork_block [Preset: mainnet] OK
+ EF - Electra - Transition - transition_only_blocks_post_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_randomized_state [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_activation_at_fork_epoch [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_attester_slashing_right_after_fork [Preset: ma OK
+ EF - Electra - Transition - transition_with_attester_slashing_right_before_fork [Preset: m OK
+ EF - Electra - Transition - transition_with_btec_right_after_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_btec_right_before_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_deposit_right_after_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_deposit_right_before_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_finality [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_leaking_at_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_leaking_pre_fork [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_no_attestations_until_after_fork [Preset: main OK
+ EF - Electra - Transition - transition_with_non_empty_activation_queue [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_one_fourth_exiting_validators_exit_at_fork [Pr OK
+ EF - Electra - Transition - transition_with_proposer_slashing_right_after_fork [Preset: ma OK
+ EF - Electra - Transition - transition_with_proposer_slashing_right_before_fork [Preset: m OK
+ EF - Electra - Transition - transition_with_random_half_participation [Preset: mainnet] OK
+ EF - Electra - Transition - transition_with_random_three_quarters_participation [Preset: m OK
```
OK: 25/25 Fail: 0/25 Skip: 0/25
## EF - Light client - Single merkle proof [Preset: mainnet]
```diff
+ Light client - Single merkle proof - mainnet/altair/light_client/single_merkle_proof/Beaco OK
@ -3643,4 +3688,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88
OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL---
OK: 2933/2953 Fail: 0/2953 Skip: 20/2953
OK: 2970/2990 Fail: 0/2990 Skip: 20/2990

View File

@ -2673,6 +2673,24 @@ OK: 5/5 Fail: 0/5 Skip: 0/5
+ [Valid] EF - Electra - Finality - finality_rule_4 [Preset: minimal] OK
```
OK: 5/5 Fail: 0/5 Skip: 0/5
## EF - Electra - Fork [Preset: minimal]
```diff
+ EF - Electra - Fork - electra_fork_random_0 [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_1 [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_2 [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_3 [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_large_validator_set [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_low_balances [Preset: minimal] OK
+ EF - Electra - Fork - electra_fork_random_misc_balances [Preset: minimal] OK
+ EF - Electra - Fork - fork_base_state [Preset: minimal] OK
+ EF - Electra - Fork - fork_many_next_epoch [Preset: minimal] OK
+ EF - Electra - Fork - fork_next_epoch [Preset: minimal] OK
+ EF - Electra - Fork - fork_next_epoch_with_block [Preset: minimal] OK
+ EF - Electra - Fork - fork_random_large_validator_set [Preset: minimal] OK
+ EF - Electra - Fork - fork_random_low_balances [Preset: minimal] OK
+ EF - Electra - Fork - fork_random_misc_balances [Preset: minimal] OK
```
OK: 14/14 Fail: 0/14 Skip: 0/14
## EF - Electra - Operations - Attestation [Preset: minimal]
```diff
+ [Invalid] EF - Electra - Operations - Attestation - invalid_after_max_inclusion_slot OK
@ -3263,6 +3281,40 @@ OK: 83/83 Fail: 0/83 Skip: 0/83
+ EF - Electra - Slots - slots_2 [Preset: minimal] OK
```
OK: 6/6 Fail: 0/6 Skip: 0/6
## EF - Electra - Transition [Preset: minimal]
```diff
+ EF - Electra - Transition - higher_churn_limit_to_lower [Preset: minimal] OK
+ EF - Electra - Transition - non_empty_historical_roots [Preset: minimal] OK
+ EF - Electra - Transition - normal_transition [Preset: minimal] OK
+ EF - Electra - Transition - simple_transition [Preset: minimal] OK
+ EF - Electra - Transition - transition_attestation_from_previous_fork_with_new_range [Pres OK
+ EF - Electra - Transition - transition_missing_first_post_block [Preset: minimal] OK
+ EF - Electra - Transition - transition_missing_last_pre_fork_block [Preset: minimal] OK
+ EF - Electra - Transition - transition_only_blocks_post_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_randomized_state [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_activation_at_fork_epoch [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_attester_slashing_right_after_fork [Preset: mi OK
+ EF - Electra - Transition - transition_with_attester_slashing_right_before_fork [Preset: m OK
+ EF - Electra - Transition - transition_with_btec_right_after_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_btec_right_before_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_deposit_right_after_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_deposit_right_before_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_finality [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_leaking_at_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_leaking_pre_fork [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_no_attestations_until_after_fork [Preset: mini OK
+ EF - Electra - Transition - transition_with_non_empty_activation_queue [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_one_fourth_exiting_validators_exit_at_fork [Pr OK
+ EF - Electra - Transition - transition_with_one_fourth_exiting_validators_exit_post_fork [ OK
+ EF - Electra - Transition - transition_with_one_fourth_slashed_active_validators_pre_fork OK
+ EF - Electra - Transition - transition_with_proposer_slashing_right_after_fork [Preset: mi OK
+ EF - Electra - Transition - transition_with_proposer_slashing_right_before_fork [Preset: m OK
+ EF - Electra - Transition - transition_with_random_half_participation [Preset: minimal] OK
+ EF - Electra - Transition - transition_with_random_three_quarters_participation [Preset: m OK
+ EF - Electra - Transition - transition_with_voluntary_exit_right_after_fork [Preset: minim OK
+ EF - Electra - Transition - transition_with_voluntary_exit_right_before_fork [Preset: mini OK
```
OK: 30/30 Fail: 0/30 Skip: 0/30
## EF - Light client - Single merkle proof [Preset: minimal]
```diff
+ Light client - Single merkle proof - minimal/altair/light_client/single_merkle_proof/Beaco OK
@ -3953,4 +4005,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207
OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL---
OK: 3212/3235 Fail: 0/3235 Skip: 23/3235
OK: 3256/3279 Fail: 0/3279 Skip: 23/3279

View File

@ -1365,6 +1365,7 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
for gossipFork in oldGossipForks:
removeMessageHandlers[gossipFork](node, forkDigests[gossipFork])
debugRaiseAssert "electra does have different gossip, add add/RemoveElectraFoo"
const addMessageHandlers: array[ConsensusFork, auto] = [
addPhase0MessageHandlers,
addAltairMessageHandlers,

View File

@ -14,7 +14,7 @@ import
./datatypes/[phase0, altair, bellatrix],
"."/[eth2_merkleization, forks, signatures, validator]
from std/algorithm import fill
from std/algorithm import fill, sort
from std/sequtils import anyIt, mapIt, toSeq
from ./datatypes/capella import BeaconState, ExecutionPayloadHeader, Withdrawal
@ -1214,7 +1214,7 @@ func get_active_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
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/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)
@ -1540,6 +1540,18 @@ func translate_participation(
state.previous_epoch_participation[index] =
add_flag(state.previous_epoch_participation.item(index), flag_index)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#new-queue_entire_balance_and_reset_validator
func queue_entire_balance_and_reset_validator(
state: var electra.BeaconState, index: uint64) =
let balance = state.balances.item(index)
state.balances[index] = 0.Gwei
let validator = addr state.validators.mitem(index)
validator[].effective_balance = 0.Gwei
validator[].activation_eligibility_epoch = FAR_FUTURE_EPOCH
debugRaiseAssert "check hashlist add return"
discard state.pending_balance_deposits.add PendingBalanceDeposit(
index: index, amount: balance)
func upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState):
ref altair.BeaconState =
var
@ -1829,9 +1841,10 @@ func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
historical_summaries: pre.historical_summaries
)
func upgrade_to_electra*(cfg: RuntimeConfig, pre: deneb.BeaconState):
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/fork.md#upgrading-the-state
func upgrade_to_electra*(
cfg: RuntimeConfig, pre: deneb.BeaconState, cache: var StateCache):
ref electra.BeaconState =
debugRaiseAssert "verify upgrade_to_electra"
let
epoch = get_current_epoch(pre)
latest_execution_payload_header = electra.ExecutionPayloadHeader(
@ -1850,18 +1863,32 @@ func upgrade_to_electra*(cfg: RuntimeConfig, pre: deneb.BeaconState):
block_hash: pre.latest_execution_payload_header.block_hash,
transactions_root: pre.latest_execution_payload_header.transactions_root,
withdrawals_root: pre.latest_execution_payload_header.withdrawals_root,
blob_gas_used: 0, # [New in Deneb]
excess_blob_gas: 0 # [New in Deneb]
blob_gas_used: 0,
excess_blob_gas: 0,
deposit_receipts_root: ZERO_HASH, # [New in Electra:EIP6110]
withdrawal_requests_root: ZERO_HASH, # [New in ELectra:EIP7002]
)
(ref electra.BeaconState)(
var max_exit_epoch = FAR_FUTURE_EPOCH
for v in pre.validators:
if v.exit_epoch != FAR_FUTURE_EPOCH:
max_exit_epoch =
if max_exit_epoch == FAR_FUTURE_EPOCH:
v.exit_epoch
else:
max(max_exit_epoch, v.exit_epoch)
if max_exit_epoch == FAR_FUTURE_EPOCH:
max_exit_epoch = get_current_epoch(pre)
let earliest_exit_epoch = max_exit_epoch + 1
let post = (ref electra.BeaconState)(
# Versioning
genesis_time: pre.genesis_time,
genesis_validators_root: pre.genesis_validators_root,
slot: pre.slot,
fork: Fork(
previous_version: pre.fork.current_version,
current_version: cfg.ELECTRA_FORK_VERSION, # [Modified in Deneb]
current_version: cfg.ELECTRA_FORK_VERSION, # [Modified in Electra:EIP6110]
epoch: epoch
),
@ -1904,16 +1931,55 @@ func upgrade_to_electra*(cfg: RuntimeConfig, pre: deneb.BeaconState):
next_sync_committee: pre.next_sync_committee,
# Execution-layer
latest_execution_payload_header: latest_execution_payload_header, # [Modified in Deneb]
latest_execution_payload_header: latest_execution_payload_header,
# Withdrawals
next_withdrawal_index: pre.next_withdrawal_index,
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
# Deep history valid from Capella onwards
historical_summaries: pre.historical_summaries
historical_summaries: pre.historical_summaries,
# [New in Electra:EIP6110]
deposit_receipts_start_index: UNSET_DEPOSIT_RECEIPTS_START_INDEX,
# [New in Electra:EIP7251]
deposit_balance_to_consume: 0.Gwei,
exit_balance_to_consume: 0.Gwei,
earliest_exit_epoch: earliest_exit_epoch,
consolidation_balance_to_consume: 0.Gwei,
earliest_consolidation_epoch:
compute_activation_exit_epoch(get_current_epoch(pre))
# pending_balance_deposits, pending_partial_withdrawals, and
# pending_consolidations are default empty lists
)
post.exit_balance_to_consume =
get_activation_exit_churn_limit(cfg, post[], cache)
post.consolidation_balance_to_consume =
get_consolidation_churn_limit(cfg, post[], cache)
# [New in Electra:EIP7251]
# add validators that are not yet active to pending balance deposits
var pre_activation: seq[(Epoch, uint64)]
for index, validator in post.validators:
if validator.activation_epoch == FAR_FUTURE_EPOCH:
pre_activation.add((validator.activation_eligibility_epoch, index.uint64))
sort(pre_activation)
for (_, index) in pre_activation:
queue_entire_balance_and_reset_validator(post[], index)
# Ensure early adopters of compounding credentials go through the activation
# churn
for index, validator in post.validators:
if has_compounding_withdrawal_credential(validator):
debugRaiseAssert "in theory truncating"
queue_excess_active_balance(post[], ValidatorIndex(index))
post
func latest_block_root(state: ForkyBeaconState, state_root: Eth2Digest):
Eth2Digest =
# The root of the last block that was successfully applied to this state -

View File

@ -217,24 +217,26 @@ func maybeUpgradeStateToDeneb(
root: hash_tree_root(newState[]), data: newState[]))[]
func maybeUpgradeStateToElectra(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState) =
cfg: RuntimeConfig, state: var ForkedHashedBeaconState,
cache: var StateCache) =
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
if getStateField(state, slot).epoch == cfg.ELECTRA_FORK_EPOCH and
state.kind == ConsensusFork.Deneb:
let newState = upgrade_to_electra(cfg, state.denebData.data)
let newState = upgrade_to_electra(cfg, state.denebData.data, cache)
state = (ref ForkedHashedBeaconState)(
kind: ConsensusFork.Electra,
electraData: electra.HashedBeaconState(
root: hash_tree_root(newState[]), data: newState[]))[]
func maybeUpgradeState*(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState) =
cfg: RuntimeConfig, state: var ForkedHashedBeaconState,
cache: var StateCache) =
cfg.maybeUpgradeStateToAltair(state)
cfg.maybeUpgradeStateToBellatrix(state)
cfg.maybeUpgradeStateToCapella(state)
cfg.maybeUpgradeStateToDeneb(state)
cfg.maybeUpgradeStateToElectra(state)
cfg.maybeUpgradeStateToElectra(state, cache)
proc process_slots*(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState, slot: Slot,
@ -257,7 +259,7 @@ proc process_slots*(
# block after
forkyState.root = hash_tree_root(forkyState.data)
maybeUpgradeState(cfg, state)
maybeUpgradeState(cfg, state, cache)
ok()

View File

@ -29,11 +29,16 @@ proc runTest(
postState = newClone(
parseTest(testDir/"post.ssz_snappy", SSZ, BeaconStatePost))
var cfg = defaultRuntimeConfig
var
cfg = defaultRuntimeConfig
cache: StateCache
when BeaconStateAnte is phase0.BeaconState:
cfg.ALTAIR_FORK_EPOCH = preState[].slot.epoch
let upgradedState = upgrade_func(cfg, preState[])
when compiles(upgrade_func(cfg, preState[], cache)):
let upgradedState = upgrade_func(cfg, preState[], cache)
else:
let upgradedState = upgrade_func(cfg, preState[])
check: upgradedState[].hash_tree_root() == postState[].hash_tree_root()
reportDiff(upgradedState, postState)
@ -72,3 +77,12 @@ suite "EF - Deneb - Fork " & preset():
for kind, path in walkDir(OpForkDir, relative = true, checkDir = true):
runTest(capella.BeaconState, deneb.BeaconState, "Deneb", OpForkDir,
upgrade_to_deneb, suiteName, path)
from ../../beacon_chain/spec/datatypes/electra import BeaconState
suite "EF - Electra - Fork " & preset():
const OpForkDir =
SszTestsDir/const_preset/"electra"/"fork"/"fork"/"pyspec_tests"
for kind, path in walkDir(OpForkDir, relative = true, checkDir = true):
runTest(deneb.BeaconState, electra.BeaconState, "Electra", OpForkDir,
upgrade_to_electra, suiteName, path)

View File

@ -123,30 +123,29 @@ proc loadOps(
let filename = step["block"].getStr()
doAssert step.hasKey"blobs" == step.hasKey"proofs"
withConsensusFork(fork):
when consensusFork != ConsensusFork.Electra:
let
blck = parseTest(
path/filename & ".ssz_snappy",
SSZ, consensusFork.SignedBeaconBlock)
let
blck = parseTest(
path/filename & ".ssz_snappy",
SSZ, consensusFork.SignedBeaconBlock)
blobData =
when consensusFork >= ConsensusFork.Deneb:
if step.hasKey"blobs":
numExtraFields += 2
Opt.some BlobData(
blobs: distinctBase(parseTest(
path/(step["blobs"].getStr()) & ".ssz_snappy",
SSZ, List[KzgBlob, Limit MAX_BLOBS_PER_BLOCK])),
proofs: step["proofs"].mapIt(KzgProof.fromHex(it.getStr())))
else:
Opt.none(BlobData)
blobData =
when consensusFork >= ConsensusFork.Deneb:
if step.hasKey"blobs":
numExtraFields += 2
Opt.some BlobData(
blobs: distinctBase(parseTest(
path/(step["blobs"].getStr()) & ".ssz_snappy",
SSZ, List[KzgBlob, Limit MAX_BLOBS_PER_BLOCK])),
proofs: step["proofs"].mapIt(KzgProof.fromHex(it.getStr())))
else:
doAssert not step.hasKey"blobs"
Opt.none(BlobData)
else:
doAssert not step.hasKey"blobs"
Opt.none(BlobData)
result.add Operation(kind: opOnBlock,
blck: ForkedSignedBeaconBlock.init(blck),
blobData: blobData)
result.add Operation(kind: opOnBlock,
blck: ForkedSignedBeaconBlock.init(blck),
blobData: blobData)
elif step.hasKey"attester_slashing":
let filename = step["attester_slashing"].getStr()
let attesterSlashing = parseTest(

View File

@ -146,3 +146,19 @@ suite "EF - Deneb - Transition " & preset():
capella.BeaconState, deneb.BeaconState, capella.SignedBeaconBlock,
deneb.SignedBeaconBlock, cfg, "EF - Deneb - Transition",
TransitionDir, suiteName, path, transitionInfo.fork_block)
from ../../beacon_chain/spec/datatypes/electra import
BeaconState, SignedBeaconBlock
suite "EF - Electra - Transition " & preset():
const TransitionDir =
SszTestsDir/const_preset/"electra"/"transition"/"core"/"pyspec_tests"
for kind, path in walkDir(TransitionDir, relative = true, checkDir = true):
let transitionInfo = getTransitionInfo(TransitionDir / path)
var cfg = defaultRuntimeConfig
cfg.ELECTRA_FORK_EPOCH = transitionInfo.fork_epoch.Epoch
runTest(
deneb.BeaconState, electra.BeaconState, deneb.SignedBeaconBlock,
electra.SignedBeaconBlock, cfg, "EF - Electra - Transition",
TransitionDir, suiteName, path, transitionInfo.fork_block)

View File

@ -33,9 +33,10 @@ proc initGenesisState*(
phase0Data: initialize_hashed_beacon_state_from_eth1(
cfg, mockEth1BlockHash, 0, deposits, {}))
maybeUpgradeState(cfg, result[])
var cache: StateCache
maybeUpgradeState(cfg, result[], cache)
when isMainModule:
# Smoke test
let state = initGenesisState(num_validators = SLOTS_PER_EPOCH)
doAssert state.validators.len == SLOTS_PER_EPOCH
doAssert state.validators.len == SLOTS_PER_EPOCH

View File

@ -46,7 +46,8 @@ proc makeTestDB*(
forkyState.root = hash_tree_root(forkyState.data)
# Upgrade genesis state to later fork, if required by fork schedule
cfg.maybeUpgradeState(genState[])
var cache: StateCache
cfg.maybeUpgradeState(genState[], cache)
withState(genState[]):
when consensusFork > ConsensusFork.Phase0:
forkyState.data.fork.previous_version =
@ -95,4 +96,4 @@ proc getEarliestInvalidBlockRoot*(
break
curBlck = curBlck.parent
curBlck.root
curBlck.root