Skip to content

Commit

Permalink
reduce code duplication when collecting LC data
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 committed Nov 15, 2023
1 parent 9889b84 commit 29989f9
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 29989f9

Please sign in to comment.