Skip to content

Commit

Permalink
init fulu
Browse files Browse the repository at this point in the history
  • Loading branch information
agnxsh committed Oct 24, 2024
1 parent 40f2acc commit bc39075
Show file tree
Hide file tree
Showing 20 changed files with 1,808 additions and 249 deletions.
35 changes: 24 additions & 11 deletions beacon_chain/beacon_chain_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ proc new*(T: type BeaconChainDB,
kvStore db.openKvStore("bellatrix_blocks").expectDb(),
kvStore db.openKvStore("capella_blocks").expectDb(),
kvStore db.openKvStore("deneb_blocks").expectDb(),
kvStore db.openKvStore("electra_blocks").expectDb()]
kvStore db.openKvStore("electra_blocks").expectDb(),
kvStore db.openKvStore("fulu_blocks").expectDb()]

stateRoots = kvStore db.openKvStore("state_roots", true).expectDb()

Expand All @@ -524,7 +525,8 @@ proc new*(T: type BeaconChainDB,
kvStore db.openKvStore("bellatrix_state_no_validators").expectDb(),
kvStore db.openKvStore("capella_state_no_validator_pubkeys").expectDb(),
kvStore db.openKvStore("deneb_state_no_validator_pubkeys").expectDb(),
kvStore db.openKvStore("electra_state_no_validator_pubkeys").expectDb()]
kvStore db.openKvStore("electra_state_no_validator_pubkeys").expectDb(),
kvStore db.openKvStore("fulu_state_no_validator_pubkeys").expectDb()]

stateDiffs = kvStore db.openKvStore("state_diffs").expectDb()
summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb()
Expand Down Expand Up @@ -805,7 +807,7 @@ proc putBlock*(
db: BeaconChainDB,
value: bellatrix.TrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock |
electra.TrustedSignedBeaconBlock) =
electra.TrustedSignedBeaconBlock | fulu.TrustedSignedBeaconBlock) =
db.withManyWrites:
db.blocks[type(value).kind].putSZSSZ(value.root.data, value)
db.putBeaconBlockSummary(value.root, value.message.toBeaconBlockSummary())
Expand Down Expand Up @@ -859,6 +861,10 @@ template toBeaconStateNoImmutableValidators(state: electra.BeaconState):
ElectraBeaconStateNoImmutableValidators =
isomorphicCast[ElectraBeaconStateNoImmutableValidators](state)

template toBeaconStateNoImmutableValidators(state: fulu.BeaconState):
FuluBeaconStateNoImmutableValidators =
isomorphicCast[FuluBeaconStateNoImmutableValidators](state)

proc putState*(
db: BeaconChainDB, key: Eth2Digest,
value: phase0.BeaconState | altair.BeaconState) =
Expand All @@ -869,7 +875,7 @@ proc putState*(
proc putState*(
db: BeaconChainDB, key: Eth2Digest,
value: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
electra.BeaconState) =
electra.BeaconState | fulu.BeaconState) =
db.updateImmutableValidators(value.validators.asSeq())
db.statesNoVal[type(value).kind].putSZSSZ(
key.data, toBeaconStateNoImmutableValidators(value))
Expand Down Expand Up @@ -998,7 +1004,8 @@ proc getBlock*(

proc getBlock*[
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock |
fulu.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest,
T: type X): Opt[T] =
# We only store blocks that we trust in the database
Expand Down Expand Up @@ -1053,7 +1060,8 @@ proc getBlockSSZ*(

proc getBlockSSZ*[
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock |
fulu.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte], T: type X): bool =
let dataPtr = addr data # Short-lived
var success = true
Expand Down Expand Up @@ -1102,7 +1110,8 @@ proc getBlockSZ*(

proc getBlockSZ*[
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock |
fulu.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte], T: type X): bool =
let dataPtr = addr data # Short-lived
func decode(data: openArray[byte]) =
Expand Down Expand Up @@ -1200,7 +1209,8 @@ proc getStateOnlyMutableValidators(
proc getStateOnlyMutableValidators(
immutableValidators: openArray[ImmutableValidatorData2],
store: KvStoreRef, key: openArray[byte],
output: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState),
output: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState |
fulu.BeaconState),
rollback: RollbackProc): bool =
## Load state into `output` - BeaconState is large so we want to avoid
## re-allocating it if possible
Expand Down Expand Up @@ -1285,7 +1295,8 @@ proc getState*(
proc getState*(
db: BeaconChainDB, key: Eth2Digest,
output: var (altair.BeaconState | bellatrix.BeaconState |
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
capella.BeaconState | deneb.BeaconState | electra.BeaconState |
fulu.BeaconState),
rollback: RollbackProc): bool =
## Load state into `output` - BeaconState is large so we want to avoid
## re-allocating it if possible
Expand Down Expand Up @@ -1365,7 +1376,7 @@ proc containsBlock*(
proc containsBlock*[
X: altair.TrustedSignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock |
electra.TrustedSignedBeaconBlock](
electra.TrustedSignedBeaconBlock | fulu.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest, T: type X): bool =
db.blocks[X.kind].contains(key.data).expectDb()

Expand Down Expand Up @@ -1506,7 +1517,7 @@ iterator getAncestorSummaries*(db: BeaconChainDB, root: Eth2Digest):

# Backwards compat for reading old databases, or those that for whatever
# reason lost a summary along the way..
static: doAssert ConsensusFork.high == ConsensusFork.Electra
static: doAssert ConsensusFork.high == ConsensusFork.Fulu
while true:
if db.v0.backend.getSnappySSZ(
subkey(BeaconBlockSummary, res.root), res.summary) == GetResult.found:
Expand All @@ -1523,6 +1534,8 @@ iterator getAncestorSummaries*(db: BeaconChainDB, root: Eth2Digest):
res.summary = blck.get().message.toBeaconBlockSummary()
elif (let blck = db.getBlock(res.root, electra.TrustedSignedBeaconBlock); blck.isSome()):
res.summary = blck.get().message.toBeaconBlockSummary()
elif (let blck = db.getBlock(res.root, fulu.TrustedSignedBeaconBlock); blck.isSome()):
res.summary = blck.get().message.toBeaconBlockSummary()
else:
break

Expand Down
86 changes: 86 additions & 0 deletions beacon_chain/beacon_chain_db_immutable.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ from ./spec/datatypes/deneb import ExecutionPayloadHeader
from ./spec/datatypes/electra import
ExecutionPayloadHeader, PendingConsolidation, PendingDeposit,
PendingPartialWithdrawal
from ./spec/datatypes/fulu import
ExecutionPayloadHeader

type
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beaconstate
Expand Down Expand Up @@ -416,3 +418,87 @@ type
pending_consolidations*:
HashList[PendingConsolidation, Limit PENDING_CONSOLIDATIONS_LIMIT]
## [New in Electra:EIP7251]

# Memory-representation-equivalent to a Deneb BeaconState for in-place SSZ
# reading and writing
FuluBeaconStateNoImmutableValidators* = object
# Versioning
genesis_time*: uint64
genesis_validators_root*: Eth2Digest
slot*: Slot
fork*: Fork

# History
latest_block_header*: BeaconBlockHeader
## `latest_block_header.state_root == ZERO_HASH` temporarily

block_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
## Needed to process attestations, older to newer

state_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
historical_roots*: HashList[Eth2Digest, Limit HISTORICAL_ROOTS_LIMIT]
## Frozen in Capella, replaced by historical_summaries

# Eth1
eth1_data*: Eth1Data
eth1_data_votes*:
HashList[Eth1Data, Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)]
eth1_deposit_index*: uint64

# Registry
validators*:
HashList[ValidatorStatusCapella, Limit VALIDATOR_REGISTRY_LIMIT]
balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]

# Randomness
randao_mixes*: HashArray[Limit EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest]

# Slashings
slashings*: HashArray[Limit EPOCHS_PER_SLASHINGS_VECTOR, Gwei]
## Per-epoch sums of slashed effective balances

# Participation
previous_epoch_participation*: EpochParticipationFlags
current_epoch_participation*: EpochParticipationFlags

# Finality
justification_bits*: JustificationBits
## Bit set for every recent justified epoch

previous_justified_checkpoint*: Checkpoint
current_justified_checkpoint*: Checkpoint
finalized_checkpoint*: Checkpoint

# Inactivity
inactivity_scores*: HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]

# Light client sync committees
current_sync_committee*: SyncCommittee
next_sync_committee*: SyncCommittee

# Execution
latest_execution_payload_header*: fulu.ExecutionPayloadHeader

# Withdrawals
next_withdrawal_index*: WithdrawalIndex
next_withdrawal_validator_index*: uint64

# Deep history valid from Capella onwards
historical_summaries*:
HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]

deposit_requests_start_index*: uint64 # [New in Electra:EIP6110]
deposit_balance_to_consume*: Gwei # [New in Electra:EIP7251]
exit_balance_to_consume*: Gwei # [New in Electra:EIP7251]
earliest_exit_epoch*: Epoch # [New in Electra:EIP7251]
consolidation_balance_to_consume*: Gwei # [New in Electra:EIP7251]
earliest_consolidation_epoch*: Epoch # [New in Electra:EIP7251]
pending_deposits*: HashList[PendingDeposit, Limit PENDING_DEPOSITS_LIMIT]
## [New in Electra:EIP7251]

# [New in Electra:EIP7251]
pending_partial_withdrawals*:
HashList[PendingPartialWithdrawal, Limit PENDING_PARTIAL_WITHDRAWALS_LIMIT]
pending_consolidations*:
HashList[PendingConsolidation, Limit PENDING_CONSOLIDATIONS_LIMIT]
## [New in Electra:EIP7251]
17 changes: 15 additions & 2 deletions beacon_chain/consensus_object_pools/blockchain_dag.nim
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,11 @@ proc getForkedBlock*(db: BeaconChainDB, root: Eth2Digest):
Opt[ForkedTrustedSignedBeaconBlock] =
# When we only have a digest, we don't know which fork it's from so we try
# them one by one - this should be used sparingly
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
if (let blck = db.getBlock(root, electra.TrustedSignedBeaconBlock);
static: doAssert high(ConsensusFork) == ConsensusFork.Fulu
if (let blck = db.getBlock(root, fulu.TrustedSignedBeaconBlock);
blck.isSome()):
ok(ForkedTrustedSignedBeaconBlock.init(blck.get()))
elif (let blck = db.getBlock(root, electra.TrustedSignedBeaconBlock);
blck.isSome()):
ok(ForkedTrustedSignedBeaconBlock.init(blck.get()))
elif (let blck = db.getBlock(root, deneb.TrustedSignedBeaconBlock);
Expand Down Expand Up @@ -1007,6 +1010,12 @@ proc applyBlock(
? state_transition(
dag.cfg, state, data, cache, info,
dag.updateFlags + {slotProcessed}, noRollback)
of ConsensusFork.Fulu:
let data = getBlock(dag, bid, fulu.TrustedSignedBeaconBlock).valueOr:
return err("Block load failed")
? state_transition(
dag.cfg, state, data, cache, info,
dag.updateFlags + {slotProcessed}, noRollback)

ok()

Expand Down Expand Up @@ -1168,6 +1177,7 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
of ConsensusFork.Capella: capellaFork(cfg)
of ConsensusFork.Deneb: denebFork(cfg)
of ConsensusFork.Electra: electraFork(cfg)
of ConsensusFork.Fulu: fuluFork(cfg)
stateFork = getStateField(dag.headState, fork)

# Here, we check only the `current_version` field because the spec
Expand Down Expand Up @@ -2416,6 +2426,9 @@ proc updateHead*(
of ConsensusFork.Electra:
if dag.vanityLogs.onUpgradeToElectra != nil:
dag.vanityLogs.onUpgradeToElectra()
of ConsensusFork.Fulu:
if dag.vanityLogs.onUpgradeToFulu != nil:
dag.vanityLogs.onUpgradeToFulu()

if dag.vanityLogs.onKnownBlsToExecutionChange != nil and
checkBlsToExecutionChanges(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func cacheRecentSyncAggregate(
func lightClientHeader(
blck: ForkyTrustedSignedBeaconBlock): ForkedLightClientHeader =
const lcDataFork = max(
lcDataForkAtConsensusFork(typeof(blck).kind), LightClientDataFork.Altair)
LightClientDataFork.Electra, LightClientDataFork.Altair)
ForkedLightClientHeader.init(blck.toLightClientHeader(lcDataFork))

func sync_aggregate(
Expand Down Expand Up @@ -727,6 +727,14 @@ proc createLightClientBootstrap(
bid.slot, normalize_merkle_branch(
dag.getLightClientData(bid).current_sync_committee_branch,
lcDataFork.current_sync_committee_gindex))
elif consensusFork >= ConsensusFork.Electra:
const lcDataFork = lcDataForkAtConsensusFork(ConsensusFork.Electra)
dag.lcDataStore.db.putHeader(
forkyBlck.toLightClientHeader(lcDataFork))
dag.lcDataStore.db.putCurrentSyncCommitteeBranch(
bid.slot, normalize_merkle_branch(
dag.getLightClientData(bid).current_sync_committee_branch,
lcDataFork.current_sync_committee_gindex))
else: raiseAssert "Unreachable"
ok()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import
std/tables,
../spec/datatypes/eip7594,
../spec/datatypes/fulu,
../spec/helpers

from std/sequtils import mapIt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type
# in case of chain reorgs around the upgrade.
onUpgradeToElectra*: LogProc

# Gets displayed on upgrade to Fulu. May be displayed multiple times
# in case of chain reorgs around the upgrade.
onUpgradeToFulu*: LogProc

# Created by http://beatscribe.com/ (beatscribe#1008 on Discord)
# These need to be the main body of the log not to be reformatted or escaped.

Expand All @@ -54,3 +58,6 @@ proc denebColor*() = notice "\n" & staticRead("deneb" / "color.ans")

proc electraMono*() = notice "\n" & staticRead("electra" / "mono.txt")
proc electraColor*() = notice "\n" & staticRead("electra" / "color.ans")

proc fuluMono*() = notice "\n" & staticRead("fulu" / "mono.txt")
proc fuluColor*() = notice "\n" & staticRead("fulu" / "color.ans")
2 changes: 1 addition & 1 deletion beacon_chain/era_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ iterator getBlockIds*(
# `case` ensures we're on a fork for which the `PartialBeaconState`
# definition is consistent
case db.cfg.consensusForkAtEpoch(slot.epoch)
of ConsensusFork.Phase0 .. ConsensusFork.Electra:
of ConsensusFork.Phase0 .. ConsensusFork.Fulu:
let stateSlot = (slot.era() + 1).start_slot()
if not getPartialState(
db, historical_roots, historical_summaries, stateSlot, state[]):
Expand Down
12 changes: 8 additions & 4 deletions beacon_chain/networking/network_metadata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,11 @@ when const_preset == "gnosis":

for network in [gnosisMetadata, chiadoMetadata]:
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
doAssert ConsensusFork.high == ConsensusFork.Electra
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
# Workaround until config files are FULU compatible
doAssert network.cfg.FULU_FORK_EPOCH == FAR_FUTURE_EPOCH
doAssert ConsensusFork.high == ConsensusFork.Fulu


elif const_preset == "mainnet":
when incbinEnabled:
Expand Down Expand Up @@ -320,8 +323,9 @@ elif const_preset == "mainnet":

for network in [mainnetMetadata, sepoliaMetadata, holeskyMetadata]:
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
doAssert ConsensusFork.high == ConsensusFork.Electra
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH # Workaround
doAssert network.cfg.FULU_FORK_EPOCH == FAR_FUTURE_EPOCH
doAssert ConsensusFork.high == ConsensusFork.Fulu

proc getMetadataForNetwork*(networkName: string): Eth2NetworkMetadata =
template loadRuntimeMetadata(): auto =
Expand Down
Loading

0 comments on commit bc39075

Please sign in to comment.