Skip to content

Commit

Permalink
reduce code duplication when collecting LC data (#5601)
Browse files Browse the repository at this point in the history
Replace sections that need to be maintained with every `ConsensusFork`
related to LC data collection with a generic logic that keeps working
when unrelated parts of Ethereum change.
  • Loading branch information
etan-status authored Nov 15, 2023
1 parent 9889b84 commit 0919ff0
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 37 deletions.
49 changes: 13 additions & 36 deletions beacon_chain/consensus_object_pools/blockchain_dag_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,12 @@ import
# Status libraries
stew/bitops2,
# Beacon chain internals
../spec/datatypes/[phase0, altair, bellatrix, capella, deneb],
../spec/forks,
../beacon_chain_db_light_client,
"."/[block_pools_types, blockchain_dag]

logScope: topics = "chaindag_lc"

type
HashedBeaconStateWithSyncCommittee =
deneb.HashedBeaconState |
capella.HashedBeaconState |
bellatrix.HashedBeaconState |
altair.HashedBeaconState

TrustedSignedBeaconBlockWithSyncAggregate =
deneb.TrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock |
bellatrix.TrustedSignedBeaconBlock |
altair.TrustedSignedBeaconBlock

template nextEpochBoundarySlot(slot: Slot): Slot =
## Compute the first possible epoch boundary state slot of a `Checkpoint`
## referring to a block at given slot.
Expand Down Expand Up @@ -95,8 +82,7 @@ proc existingCurrentSyncCommitteeForPeriod(
doAssert strictVerification notin dag.updateFlags
syncCommittee

template syncCommitteeRoot(
state: HashedBeaconStateWithSyncCommittee): Eth2Digest =
template syncCommitteeRoot(state: ForkyHashedBeaconState): Eth2Digest =
## Compute a root to uniquely identify `current_sync_committee` and
## `next_sync_committee`.
withEth2Hash:
Expand Down Expand Up @@ -436,7 +422,7 @@ proc getLightClientData(
except KeyError: raiseAssert "Unreachable"

proc cacheLightClientData(
dag: ChainDAGRef, state: HashedBeaconStateWithSyncCommittee, bid: BlockId) =
dag: ChainDAGRef, state: ForkyHashedBeaconState, bid: BlockId) =
## Cache data for a given block and its post-state to speed up creating future
## `LightClientUpdate` and `LightClientBootstrap` instances that refer to this
## block and state.
Expand Down Expand Up @@ -530,8 +516,8 @@ template lazy_bid(name: untyped): untyped {.dirty.} =

proc createLightClientUpdates(
dag: ChainDAGRef,
state: HashedBeaconStateWithSyncCommittee,
blck: TrustedSignedBeaconBlockWithSyncAggregate,
state: ForkyHashedBeaconState,
blck: ForkyTrustedSignedBeaconBlock,
parent_bid: BlockId,
data_fork: static LightClientDataFork) =
## Create `LightClientUpdate` instances for a given block and its post-state,
Expand Down Expand Up @@ -665,8 +651,8 @@ proc createLightClientUpdates(

proc createLightClientUpdates(
dag: ChainDAGRef,
state: HashedBeaconStateWithSyncCommittee,
blck: TrustedSignedBeaconBlockWithSyncAggregate,
state: ForkyHashedBeaconState,
blck: ForkyTrustedSignedBeaconBlock,
parent_bid: BlockId) =
# Attested block (parent) determines `LightClientUpdate` fork
withLcDataFork(dag.cfg.lcDataForkAtEpoch(parent_bid.slot.epoch)):
Expand Down Expand Up @@ -781,22 +767,13 @@ proc processNewBlockForLightClient*(
if signedBlock.message.slot < dag.lcDataStore.cache.tailSlot:
return

when signedBlock is deneb.TrustedSignedBeaconBlock:
dag.cacheLightClientData(state.denebData, signedBlock.toBlockId())
dag.createLightClientUpdates(state.denebData, signedBlock, parentBid)
elif signedBlock is capella.TrustedSignedBeaconBlock:
dag.cacheLightClientData(state.capellaData, signedBlock.toBlockId())
dag.createLightClientUpdates(state.capellaData, signedBlock, parentBid)
elif signedBlock is bellatrix.TrustedSignedBeaconBlock:
dag.cacheLightClientData(state.bellatrixData, signedBlock.toBlockId())
dag.createLightClientUpdates(state.bellatrixData, signedBlock, parentBid)
elif signedBlock is altair.TrustedSignedBeaconBlock:
dag.cacheLightClientData(state.altairData, signedBlock.toBlockId())
dag.createLightClientUpdates(state.altairData, signedBlock, parentBid)
elif signedBlock is phase0.TrustedSignedBeaconBlock:
raiseAssert "Unreachable" # `tailSlot` cannot be before Altair
const consensusFork = typeof(signedBlock).kind
when consensusFork >= ConsensusFork.Altair:
template forkyState: untyped = state.forky(consensusFork)
dag.cacheLightClientData(forkyState, signedBlock.toBlockId())
dag.createLightClientUpdates(forkyState, signedBlock, parentBid)
else:
{.error: "Unreachable".}
raiseAssert "Unreachable" # `tailSlot` cannot be before Altair

proc processHeadChangeForLightClient*(dag: ChainDAGRef) =
## Update light client data to account for a new head block.
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/spec/forks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ template withState*(x: ForkedHashedBeaconState, body: untyped): untyped =
template forkyState: untyped {.inject, used.} = x.phase0Data
body

template forky(
template forky*(
x: ForkedHashedBeaconState, kind: static ConsensusFork): untyped =
when kind == ConsensusFork.Deneb:
x.denebData
Expand Down

0 comments on commit 0919ff0

Please sign in to comment.