fix initialization of sync committee cache after loading non-epoch state

When initializing from a state that's not aligned to an epoch boundary,
an earlier state is loaded that's epoch aligned, and subsequently topped
up with the missing blocks. `dag.headSyncCommittee` is initialized prior
to topping up the missing blocks, though. If the sync committee changes
while applying the blocks (e.g., a sync committee period boundary hits),
the cached information becomes unlinked from `dag.head`, leading to
valid blocks based on that chain being rejected. To fix this, move cache
initialization after the top up with blocks. This has been observed on
Goerli by initializing from 7919502 and attempting to top up 7920111.
The block gets rejected with an invalid state root on nodes that have
restarted after setting 7920111 as head, while it gets accepted by all
other nodes. Error message is `block: state root verification failed`.
The incorrect initialization behaviour was introduced in #4592, before
which the sync committee cache was initialized after applying blocks.
This commit is contained in:
Etan Kissling 2024-04-01 00:59:28 +02:00
parent 4457334dd0
commit 171d889878
No known key found for this signature in database
GPG Key ID: B21DA824C5A3D03D
1 changed files with 4 additions and 4 deletions

View File

@ -1125,10 +1125,6 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
head = shortLog(head), tail = shortLog(dag.tail)
quit 1
withState(dag.headState):
when consensusFork >= ConsensusFork.Altair:
dag.headSyncCommittees = forkyState.data.get_sync_committee_cache(cache)
block:
# EpochRef needs an epoch boundary state
assign(dag.epochRefState, dag.headState)
@ -1143,6 +1139,10 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
dag.head = headRef
dag.heads = @[headRef]
withState(dag.headState):
when consensusFork >= ConsensusFork.Altair:
dag.headSyncCommittees = forkyState.data.get_sync_committee_cache(cache)
assign(dag.clearanceState, dag.headState)
if dag.headState.latest_block_root == tail.root: