add Capella support to Forked* (#4276)

* add Capella support to Forked*

* remove cruft

* add `OnForkyBlockAdded`
This commit is contained in:
tersec 2022-11-02 16:23:30 +00:00 committed by GitHub
parent cee5a73a31
commit 5b46f0b723
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 508 additions and 107 deletions

View File

@ -231,6 +231,22 @@ ConsensusSpecPreset-mainnet
ForkChoice - mainnet/bellatrix/fork_choice/on_merge_block/pyspec_tests/block_lookup_failed Skip
ForkChoice - mainnet/bellatrix/fork_choice/on_merge_block/pyspec_tests/too_early_for_merge Skip
ForkChoice - mainnet/bellatrix/fork_choice/on_merge_block/pyspec_tests/too_late_for_merge Skip
ForkChoice - mainnet/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_attestations_is_grea Skip
ForkChoice - mainnet/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_boost_ Skip
ForkChoice - mainnet/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_honest Skip
ForkChoice - mainnet/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_without_att Skip
ForkChoice - mainnet/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_vanilla Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/chain_no_attestations Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/discard_equivocations Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/genesis Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/proposer_boost_correct_head Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/shorter_chain_but_heavier_w Skip
ForkChoice - mainnet/capella/fork_choice/get_head/pyspec_tests/split_tie_breaker_no_attest Skip
ForkChoice - mainnet/capella/fork_choice/on_block/pyspec_tests/basic Skip
ForkChoice - mainnet/capella/fork_choice/on_block/pyspec_tests/on_block_bad_parent_root Skip
ForkChoice - mainnet/capella/fork_choice/on_block/pyspec_tests/on_block_future_block Skip
ForkChoice - mainnet/capella/fork_choice/on_block/pyspec_tests/proposer_boost Skip
ForkChoice - mainnet/capella/fork_choice/on_block/pyspec_tests/proposer_boost_root_same_sl Skip
+ ForkChoice - mainnet/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_attestations_is_great OK
+ ForkChoice - mainnet/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_boost_n OK
+ ForkChoice - mainnet/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_honest_ OK
@ -253,12 +269,16 @@ ConsensusSpecPreset-mainnet
+ Light client - Single merkle proof - mainnet/bellatrix/light_client/single_merkle_proof/py OK
+ Light client - Single merkle proof - mainnet/bellatrix/light_client/single_merkle_proof/py OK
+ Light client - Single merkle proof - mainnet/bellatrix/light_client/single_merkle_proof/py OK
Light client - Single merkle proof - mainnet/capella/light_client/single_merkle_proof/pysp Skip
Light client - Single merkle proof - mainnet/capella/light_client/single_merkle_proof/pysp Skip
Light client - Single merkle proof - mainnet/capella/light_client/single_merkle_proof/pysp Skip
+ Slots - double_empty_epoch OK
+ Slots - empty_epoch OK
+ Slots - over_epoch_boundary OK
+ Slots - slots_1 OK
+ Slots - slots_2 OK
+ Sync - mainnet/bellatrix/sync/optimistic/pyspec_tests/from_syncing_to_invalid OK
Sync - mainnet/capella/sync/optimistic/pyspec_tests/from_syncing_to_invalid Skip
+ [Invalid] EF - Altair - Sanity - Blocks - double_same_proposer_slashings_same_block [Prese OK
+ [Invalid] EF - Altair - Sanity - Blocks - double_similar_proposer_slashings_same_block [Pr OK
+ [Invalid] EF - Altair - Sanity - Blocks - double_validator_exit_same_block [Preset: mainne OK
@ -474,7 +494,7 @@ ConsensusSpecPreset-mainnet
+ fork_random_low_balances OK
+ fork_random_misc_balances OK
```
OK: 464/471 Fail: 0/471 Skip: 7/471
OK: 464/491 Fail: 0/491 Skip: 27/491
## Attestation
```diff
+ [Invalid] EF - Altair - Operations - Attestation - after_epoch_slots OK
@ -1806,4 +1826,4 @@ OK: 48/48 Fail: 0/48 Skip: 0/48
OK: 14/14 Fail: 0/14 Skip: 0/14
---TOTAL---
OK: 1553/1560 Fail: 0/1560 Skip: 7/1560
OK: 1553/1580 Fail: 0/1580 Skip: 27/1580

View File

@ -255,6 +255,30 @@ ConsensusSpecPreset-minimal
ForkChoice - minimal/bellatrix/fork_choice/on_merge_block/pyspec_tests/block_lookup_failed Skip
ForkChoice - minimal/bellatrix/fork_choice/on_merge_block/pyspec_tests/too_early_for_merge Skip
ForkChoice - minimal/bellatrix/fork_choice/on_merge_block/pyspec_tests/too_late_for_merge Skip
ForkChoice - minimal/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_honest Skip
ForkChoice - minimal/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_without_att Skip
ForkChoice - minimal/capella/fork_choice/ex_ante/pyspec_tests/ex_ante_vanilla Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/chain_no_attestations Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/discard_equivocations Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/filtered_block_tree Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/genesis Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/proposer_boost_correct_head Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/shorter_chain_but_heavier_w Skip
ForkChoice - minimal/capella/fork_choice/get_head/pyspec_tests/split_tie_breaker_no_attest Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/basic Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/new_finalized_slot_is_justi Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/new_finalized_slot_is_not_j Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/new_justified_is_later_than Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_bad_parent_root Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_before_finalized Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_checkpoints Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_finalized_skip_slo Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_finalized_skip_slo Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_future_block Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_outside_safe_slots Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/on_block_update_justified_c Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/proposer_boost Skip
ForkChoice - minimal/capella/fork_choice/on_block/pyspec_tests/proposer_boost_root_same_sl Skip
+ ForkChoice - minimal/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_with_honest_ OK
+ ForkChoice - minimal/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_sandwich_without_atte OK
+ ForkChoice - minimal/phase0/fork_choice/ex_ante/pyspec_tests/ex_ante_vanilla OK
@ -285,6 +309,9 @@ ConsensusSpecPreset-minimal
+ Light client - Single merkle proof - minimal/bellatrix/light_client/single_merkle_proof/py OK
+ Light client - Single merkle proof - minimal/bellatrix/light_client/single_merkle_proof/py OK
+ Light client - Single merkle proof - minimal/bellatrix/light_client/single_merkle_proof/py OK
Light client - Single merkle proof - minimal/capella/light_client/single_merkle_proof/pysp Skip
Light client - Single merkle proof - minimal/capella/light_client/single_merkle_proof/pysp Skip
Light client - Single merkle proof - minimal/capella/light_client/single_merkle_proof/pysp Skip
+ Light client - Sync - minimal/altair/light_client/sync/pyspec_tests/advance_finality_witho OK
+ Light client - Sync - minimal/altair/light_client/sync/pyspec_tests/light_client_sync OK
+ Light client - Sync - minimal/altair/light_client/sync/pyspec_tests/supply_sync_committee_ OK
@ -300,6 +327,7 @@ ConsensusSpecPreset-minimal
+ Slots - slots_1 OK
+ Slots - slots_2 OK
+ Sync - minimal/bellatrix/sync/optimistic/pyspec_tests/from_syncing_to_invalid OK
Sync - minimal/capella/sync/optimistic/pyspec_tests/from_syncing_to_invalid Skip
+ [Invalid] EF - Altair - Sanity - Blocks - double_same_proposer_slashings_same_block [Prese OK
+ [Invalid] EF - Altair - Sanity - Blocks - double_similar_proposer_slashings_same_block [Pr OK
+ [Invalid] EF - Altair - Sanity - Blocks - double_validator_exit_same_block [Preset: minima OK
@ -533,7 +561,7 @@ ConsensusSpecPreset-minimal
+ fork_random_low_balances OK
+ fork_random_misc_balances OK
```
OK: 523/530 Fail: 0/530 Skip: 7/530
OK: 523/558 Fail: 0/558 Skip: 35/558
## Attestation
```diff
+ [Invalid] EF - Altair - Operations - Attestation - after_epoch_slots OK
@ -1925,4 +1953,4 @@ OK: 52/52 Fail: 0/52 Skip: 0/52
OK: 14/14 Fail: 0/14 Skip: 0/14
---TOTAL---
OK: 1660/1667 Fail: 0/1667 Skip: 7/1667
OK: 1660/1695 Fail: 0/1695 Skip: 35/1695

View File

@ -20,6 +20,8 @@ import
./spec/datatypes/[phase0, altair, bellatrix],
"."/[beacon_chain_db_light_client, filepath]
from ./spec/datatypes/capella import BeaconState
export
phase0, altair, eth2_ssz_serialization, eth2_merkleization, kvstore,
kvstore_sqlite3
@ -445,6 +447,12 @@ proc new*(T: type BeaconChainDB,
if db.exec("DROP TABLE IF EXISTS validatorIndexFromPubKey;").isErr:
debug "Failed to drop the validatorIndexFromPubKey table"
const capellaImplementationMissingDb: KvStoreRef =
if capellaImplementationMissing:
default(KvStoreRef)
else:
default(KvStoreRef)
var
# V0 compatibility tables - these were created WITHOUT ROWID which is slow
# for large blobs
@ -463,14 +471,16 @@ proc new*(T: type BeaconChainDB,
blocks = [
kvStore db.openKvStore("blocks").expectDb(),
kvStore db.openKvStore("altair_blocks").expectDb(),
kvStore db.openKvStore("bellatrix_blocks").expectDb()]
kvStore db.openKvStore("bellatrix_blocks").expectDb(),
capellaImplementationMissingDb]
stateRoots = kvStore db.openKvStore("state_roots", true).expectDb()
statesNoVal = [
kvStore db.openKvStore("state_no_validators2").expectDb(),
kvStore db.openKvStore("altair_state_no_validators").expectDb(),
kvStore db.openKvStore("bellatrix_state_no_validators").expectDb()]
kvStore db.openKvStore("bellatrix_state_no_validators").expectDb(),
capellaImplementationMissingDb]
stateDiffs = kvStore db.openKvStore("state_diffs").expectDb()
summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb()
@ -668,9 +678,17 @@ proc close*(db: BeaconChainDB) =
db.finalizedBlocks.close()
discard db.summaries.close()
discard db.stateDiffs.close()
for kv in db.statesNoVal: discard kv.close()
for kv in db.statesNoVal:
# The scaffolding currently creates nil databases
if (capellaImplementationMissing == capellaImplementationMissing) and
not (kv.isNil):
discard kv.close()
discard db.stateRoots.close()
for kv in db.blocks: discard kv.close()
for kv in db.blocks:
# The scaffolding currently creates nil databases
if (capellaImplementationMissing == capellaImplementationMissing) and
not (kv.isNil):
discard kv.close()
discard db.keyValues.close()
db.immutableValidatorsDb.close()
@ -705,6 +723,11 @@ proc putBlock*(
db.blocks[type(value).toFork].putSZSSZ(value.root.data, value)
db.putBeaconBlockSummary(value.root, value.message.toBeaconBlockSummary())
proc putBlock*(
db: BeaconChainDB,
value: capella.TrustedSignedBeaconBlock) =
raiseAssert $capellaImplementationMissing
proc updateImmutableValidators*(
db: BeaconChainDB, validators: openArray[Validator]) =
# Must be called before storing a state that references the new validators
@ -743,6 +766,9 @@ proc putState*(db: BeaconChainDB, key: Eth2Digest, value: bellatrix.BeaconState)
db.statesNoVal[type(value).toFork()].putSZSSZ(
key.data, toBeaconStateNoImmutableValidators(value))
proc putState*(db: BeaconChainDB, key: Eth2Digest, value: capella.BeaconState) =
raiseAssert $capellaImplementationMissing
proc putState*(db: BeaconChainDB, state: ForkyHashedBeaconState) =
db.withManyWrites:
db.putStateRoot(state.latest_block_root, state.data.slot, state.root)
@ -770,12 +796,20 @@ proc putStateDiff*(db: BeaconChainDB, root: Eth2Digest, value: BeaconStateDiff)
proc delBlock*(db: BeaconChainDB, key: Eth2Digest) =
db.withManyWrites:
for kv in db.blocks: kv.del(key.data).expectDb()
for kv in db.blocks:
# The scaffolding currently creates nil databases
if (capellaImplementationMissing == capellaImplementationMissing) and
not (kv.isNil):
kv.del(key.data).expectDb()
db.summaries.del(key.data).expectDb()
proc delState*(db: BeaconChainDB, key: Eth2Digest) =
db.withManyWrites:
for kv in db.statesNoVal: kv.del(key.data).expectDb()
for kv in db.statesNoVal:
# The scaffolding currently creates nil databases
if (capellaImplementationMissing == capellaImplementationMissing) and
not (kv.isNil):
kv.del(key.data).expectDb()
proc delStateRoot*(db: BeaconChainDB, root: Eth2Digest, slot: Slot) =
db.stateRoots.del(stateRootKey(root, slot)).expectDb()
@ -842,6 +876,12 @@ proc getBlock*[
else:
result.err()
proc getBlock*[
X: capella.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest,
T: type X): Opt[T] =
raiseAssert $capellaImplementationMissing
proc getPhase0BlockSSZ(
db: BeaconChainDBV0, key: Eth2Digest, data: var seq[byte]): bool =
let dataPtr = addr data # Short-lived
@ -905,6 +945,8 @@ proc getBlockSSZ*(
getBlockSSZ(db, key, data, altair.TrustedSignedBeaconBlock)
of BeaconBlockFork.Bellatrix:
getBlockSSZ(db, key, data, bellatrix.TrustedSignedBeaconBlock)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
proc getBlockSZ*(
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte],
@ -948,6 +990,8 @@ proc getBlockSZ*(
getBlockSZ(db, key, data, altair.TrustedSignedBeaconBlock)
of BeaconBlockFork.Bellatrix:
getBlockSZ(db, key, data, bellatrix.TrustedSignedBeaconBlock)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
proc getStateOnlyMutableValidators(
immutableValidators: openArray[ImmutableValidatorData2],
@ -1101,6 +1145,12 @@ proc getState*(
db.immutableValidators, db.statesNoVal[T.toFork], key.data, output,
rollback)
proc getState*(
db: BeaconChainDB, key: Eth2Digest,
output: var capella.BeaconState,
rollback: RollbackProc): bool =
raiseAssert $capellaImplementationMissing
proc getState*(
db: BeaconChainDB, fork: BeaconStateFork, state_root: Eth2Digest,
state: var ForkedHashedBeaconState, rollback: RollbackProc): bool =

View File

@ -25,6 +25,8 @@ import
../fork_choice/fork_choice,
../beacon_clock
from ../spec/datatypes/capella import HashedBeaconState, shortLog
export tables, results, phase0, altair, bellatrix, blockchain_dag, fork_choice
const
@ -144,7 +146,9 @@ proc init*(T: type AttestationPool, dag: ChainDAGRef,
var unrealized: FinalityCheckpoints
if enableTestFeatures in dag.updateFlags and blckRef == dag.head:
unrealized = withState(dag.headState):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
forkyState.data.compute_unrealized_finality()
else:
var cache: StateCache
@ -580,6 +584,9 @@ proc getAttestationsForBlock*(pool: var AttestationPool,
AttestationCache.init(state)
elif state is altair.HashedBeaconState or state is bellatrix.HashedBeaconState:
AttestationCache.init(state, cache)
elif state is capella.HashedBeaconState:
if true: raiseAssert $capellaImplementationMissing
default(AttestationCache)
else:
static: doAssert false
@ -644,6 +651,9 @@ proc getAttestationsForBlock*(pool: var AttestationPool,
elif state is phase0.HashedBeaconState:
state.data.previous_epoch_attestations.maxLen -
state.data.previous_epoch_attestations.len()
elif state is capella.HashedBeaconState:
if true: raiseAssert $capellaImplementationMissing
int(capellaImplementationMissing)
else:
raiseAssert "invalid HashedBeaconState fork"

View File

@ -18,6 +18,9 @@ import
state_transition, state_transition_epoch],
"."/[block_dag, blockchain_dag, blockchain_dag_light_client]
# TODO remove when forks re-exports this
from ../spec/datatypes/capella import asSigVerified, asTrusted, shortLog
export results, signatures_batch, block_dag, blockchain_dag
# Clearance
@ -36,7 +39,7 @@ proc addResolvedHeadBlock(
trustedBlock: ForkyTrustedSignedBeaconBlock,
blockVerified: bool,
parent: BlockRef, cache: var StateCache,
onBlockAdded: OnPhase0BlockAdded | OnAltairBlockAdded | OnBellatrixBlockAdded,
onBlockAdded: OnForkyBlockAdded,
stateDataDur, sigVerifyDur, stateVerifyDur: Duration
): BlockRef =
doAssert state.matches_block_slot(
@ -104,7 +107,9 @@ proc addResolvedHeadBlock(
var unrealized: FinalityCheckpoints
if enableTestFeatures in dag.updateFlags:
unrealized = withState(state):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
forkyState.data.compute_unrealized_finality()
else:
forkyState.data.compute_unrealized_finality(cache)
@ -161,8 +166,7 @@ proc addHeadBlock*(
dag: ChainDAGRef, verifier: var BatchVerifier,
signedBlock: ForkySignedBeaconBlock,
blockVerified: bool,
onBlockAdded: OnPhase0BlockAdded | OnAltairBlockAdded |
OnBellatrixBlockAdded
onBlockAdded: OnForkyBlockAdded
): Result[BlockRef, BlockError] =
## Try adding a block to the chain, verifying first that it passes the state
## transition function and contains correct cryptographic signature.
@ -291,8 +295,7 @@ proc addHeadBlock*(
proc addHeadBlock*(
dag: ChainDAGRef, verifier: var BatchVerifier,
signedBlock: ForkySignedBeaconBlock,
onBlockAdded: OnPhase0BlockAdded | OnAltairBlockAdded |
OnBellatrixBlockAdded
onBlockAdded: OnForkyBlockAdded
): Result[BlockRef, BlockError] =
addHeadBlock(
dag, verifier, signedBlock, blockVerified = true, onBlockAdded)

View File

@ -15,6 +15,9 @@ import
../spec/datatypes/[phase0, altair, bellatrix],
../spec/forks
# TODO remove once forks re-exports these
from ../spec/datatypes/capella import SomeBeaconBlock, TrustedBeaconBlock
export chronicles, forks
type
@ -67,7 +70,8 @@ func init*(
func init*(
T: type BlockRef, root: Eth2Digest,
blck: bellatrix.SomeBeaconBlock | bellatrix.TrustedBeaconBlock): BlockRef =
blck: bellatrix.SomeBeaconBlock | bellatrix.TrustedBeaconBlock |
capella.SomeBeaconBlock | capella.TrustedBeaconBlock): BlockRef =
BlockRef.init(
root, some Eth2Digest(blck.body.execution_payload.block_hash), blck.slot)

View File

@ -22,6 +22,8 @@ import
../validators/validator_monitor,
./block_dag, block_pools_types_light_client
from ../spec/datatypes/capella import TrustedSignedBeaconBlock
from "."/vanity_logs/pandas import VanityLogs
export
@ -303,6 +305,16 @@ type
epochRef: EpochRef,
unrealized: FinalityCheckpoints) {.gcsafe, raises: [Defect].}
OnCapellaBlockAdded* = proc(
blckRef: BlockRef,
blck: capella.TrustedSignedBeaconBlock,
epochRef: EpochRef,
unrealized: FinalityCheckpoints) {.gcsafe, raises: [Defect].}
OnForkyBlockAdded* =
OnPhase0BlockAdded | OnAltairBlockAdded | OnBellatrixBlockAdded |
OnCapellaBlockAdded
HeadChangeInfoObject* = object
slot*: Slot
block_root* {.serializedFieldName: "block".}: Eth2Digest

View File

@ -20,6 +20,8 @@ import
".."/[beacon_chain_db, era_db],
"."/[block_pools_types, block_quarantine]
from ../spec/datatypes/capella import shortLog
export
eth2_merkleization, eth2_ssz_serialization,
block_pools_types, results, beacon_chain_db
@ -842,6 +844,8 @@ proc applyBlock(
state_transition(
dag.cfg, state, data, cache, info,
dag.updateFlags + {slotProcessed}, noRollback)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
validatorMonitor: ref ValidatorMonitor, updateFlags: UpdateFlags,
@ -998,6 +1002,7 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
of BeaconStateFork.Phase0: genesisFork(cfg)
of BeaconStateFork.Altair: altairFork(cfg)
of BeaconStateFork.Bellatrix: bellatrixFork(cfg)
of BeaconStateFork.Capella: capellaFork(cfg)
stateFork = getStateField(dag.headState, fork)
if stateFork != configFork:

View File

@ -18,6 +18,8 @@ import
../beacon_chain_db_light_client,
"."/[block_pools_types, blockchain_dag]
from ../spec/datatypes/capella import TrustedSignedBeaconBlock
logScope: topics = "chaindag_lc"
type
@ -118,7 +120,9 @@ proc syncCommitteeRootForPeriod(
bsi = ? dag.getExistingBlockIdAtSlot(syncCommitteeSlot)
dag.withUpdatedExistingState(tmpState, bsi) do:
withState(state):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
ok forkyState.syncCommitteeRoot
else: raiseAssert "Unreachable"
do: err()
@ -351,7 +355,9 @@ proc initLightClientUpdateForPeriod(
dag.handleUnexpectedLightClientError(bid.slot)
return err()
withStateAndBlck(state, bdata):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
update.attested_header = blck.toBeaconBlockHeader()
update.next_sync_committee = forkyState.data.next_sync_committee
update.next_sync_committee_branch =
@ -377,7 +383,9 @@ proc initLightClientUpdateForPeriod(
dag.handleUnexpectedLightClientError(signatureBid.slot)
return err()
withBlck(bdata):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
update.sync_aggregate = blck.asSigned().message.body.sync_aggregate
else: raiseAssert "Unreachable"
update.signature_slot = signatureBid.slot
@ -612,7 +620,9 @@ proc initLightClientDataCache*(dag: ChainDAGRef) =
if dag.head.slot < dag.lcDataStore.cache.tailSlot:
return
withState(dag.headState):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
dag.cacheLightClientData(forkyState, dag.head.bid)
else: raiseAssert "Unreachable" # `tailSlot` cannot be before Altair
if dag.lcDataStore.importMode == LightClientDataImportMode.OnlyNew:
@ -663,7 +673,9 @@ proc initLightClientDataCache*(dag: ChainDAGRef) =
res.err()
continue
withStateAndBlck(dag.headState, bdata):
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
# Cache light client data (non-finalized blocks may refer to this)
if i != blocks.low:
dag.cacheLightClientData(forkyState, bid) # `dag.head` already cached
@ -708,7 +720,9 @@ proc processNewBlockForLightClient*(
if signedBlock.message.slot < dag.lcDataStore.cache.tailSlot:
return
when signedBlock is bellatrix.TrustedSignedBeaconBlock:
when signedBlock is capella.TrustedSignedBeaconBlock:
raiseAssert $capellaImplementationMissing
elif signedBlock is bellatrix.TrustedSignedBeaconBlock:
dag.cacheLightClientData(state.bellatrixData, signedBlock.toBlockId())
dag.createLightClientUpdates(state.bellatrixData, signedBlock, parentBid)
elif signedBlock is altair.TrustedSignedBeaconBlock:
@ -746,7 +760,9 @@ proc processHeadChangeForLightClient*(dag: ChainDAGRef) =
dag.lcDataStore.db.putBestUpdate(
period, dag.lcDataStore.cache.pendingBest.getOrDefault(key))
withState(dag.headState): # Common case separate to avoid `tmpState` copy
when stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
let key = (headPeriod, forkyState.syncCommitteeRoot)
dag.lcDataStore.db.putBestUpdate(
headPeriod, dag.lcDataStore.cache.pendingBest.getOrDefault(key))

View File

@ -365,6 +365,8 @@ iterator getBlockIds*(
let stateSlot = (slot.era() + 1).start_slot()
if not getPartialState(db, historical_roots, stateSlot, state[]):
state = nil # No `return` in iterators
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
if state == nil:
break

View File

@ -286,6 +286,14 @@ proc newExecutionPayload*(
error "newPayload failed", msg = err.msg
return Opt.none PayloadExecutionStatus
# TODO when forks re-exports this, remove
from ../spec/datatypes/capella import ExecutionPayload
proc newExecutionPayload*(
eth1Monitor: Eth1Monitor, executionPayload: capella.ExecutionPayload):
Future[Opt[PayloadExecutionStatus]] {.async.} =
raiseAssert $capellaImplementationMissing
proc getExecutionValidity(
eth1Monitor: Eth1Monitor,
blck: phase0.SignedBeaconBlock | altair.SignedBeaconBlock):
@ -327,6 +335,15 @@ proc getExecutionValidity(
error "getExecutionValidity: newPayload failed", err = err.msg
return NewPayloadStatus.noResponse
# TODO drop when forks re-exports all this
from ../spec/datatypes/capella import SignedBeaconBlock, asTrusted, shortLog
proc getExecutionValidity(
eth1Monitor: Eth1Monitor,
blck: capella.SignedBeaconBlock):
Future[NewPayloadStatus] {.async.} =
raiseAssert $capellaImplementationMissing
proc storeBlock*(
self: ref BlockProcessor, src: MsgSource, wallTime: BeaconTime,
signedBlock: ForkySignedBeaconBlock, queueTick: Moment = Moment.now(),

View File

@ -24,6 +24,8 @@ import
".."/[beacon_clock],
./batch_validation
from ../spec/datatypes/capella import SignedBeaconBlock
from libp2p/protocols/pubsub/pubsub import ValidationResult
export results, ValidationResult
@ -385,6 +387,12 @@ proc validateBeaconBlock*(
ok()
proc validateBeaconBlock*(
dag: ChainDAGRef, quarantine: ref Quarantine,
signed_beacon_block: capella.SignedBeaconBlock,
wallTime: BeaconTime, flags: UpdateFlags): Result[void, ValidationError] =
raiseAssert $capellaImplementationMissing
# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
proc validateAttestation*(
pool: ref AttestationPool,

View File

@ -2625,6 +2625,14 @@ proc broadcastBeaconBlock*(
let topic = getBeaconBlocksTopic(node.forkDigests.bellatrix)
node.broadcast(topic, blck)
# TODO when forks re-exports this, use that instead and rm this
from ../spec/datatypes/capella import SignedBeaconBlock
proc broadcastBeaconBlock*(
node: Eth2Node, blck: capella.SignedBeaconBlock): Future[SendResult] =
let topic = getBeaconBlocksTopic(node.forkDigests.capella)
node.broadcast(topic, blck)
proc broadcastBeaconBlock*(
node: Eth2Node, forked: ForkedSignedBeaconBlock): Future[SendResult] =
withBlck(forked): node.broadcastBeaconBlock(blck)

View File

@ -759,7 +759,8 @@ func forkDigests(node: BeaconNode): auto =
let forkDigestsArray: array[BeaconStateFork, auto] = [
node.dag.forkDigests.phase0,
node.dag.forkDigests.altair,
node.dag.forkDigests.bellatrix]
node.dag.forkDigests.bellatrix,
node.dag.forkDigests.capella]
forkDigestsArray
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/validator.md#phase-0-attestation-subnet-stability
@ -1108,7 +1109,8 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
const removeMessageHandlers: array[BeaconStateFork, auto] = [
removePhase0MessageHandlers,
removeAltairMessageHandlers,
removeAltairMessageHandlers # with different forkDigest
removeAltairMessageHandlers, # with different forkDigest
if capellaImplementationMissing: removeAltairMessageHandlers else: removeAltairMessageHandlers
]
for gossipFork in oldGossipForks:
@ -1117,7 +1119,8 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
const addMessageHandlers: array[BeaconStateFork, auto] = [
addPhase0MessageHandlers,
addAltairMessageHandlers,
addAltairMessageHandlers # with different forkDigest
addAltairMessageHandlers, # with different forkDigest
if capellaImplementationMissing: addAltairMessageHandlers else: addAltairMessageHandlers
]
for gossipFork in newGossipForks:

View File

@ -276,6 +276,9 @@ proc getStateOptimistic*(node: BeaconNode,
doAssert forkyState.data.slot > 0
some[bool](node.dag.is_optimistic(
get_block_root_at_slot(forkyState.data, forkyState.data.slot - 1)))
of BeaconStateFork.Capella:
if true: raiseAssert $capellaImplementationMissing
none[bool]()
else:
none[bool]()
@ -288,6 +291,9 @@ proc getBlockOptimistic*(node: BeaconNode,
some[bool](false)
of BeaconBlockFork.Bellatrix:
some[bool](node.dag.is_optimistic(blck.root))
of BeaconBlockFork.Capella:
if true: raiseAssert $capellaImplementationMissing
none[bool]()
else:
none[bool]()
@ -298,6 +304,9 @@ proc getBlockRefOptimistic*(node: BeaconNode, blck: BlockRef): bool =
false
of BeaconBlockFork.Bellatrix:
node.dag.is_optimistic(blck.root)
of BeaconBlockFork.Capella:
if true: raiseAssert $capellaImplementationMissing
true
const
jsonMediaType* = MediaType.init("application/json")

View File

@ -361,6 +361,18 @@ func get_initial_beacon_block*(state: bellatrix.HashedBeaconState):
bellatrix.TrustedSignedBeaconBlock(
message: message, root: hash_tree_root(message))
# https://github.com/ethereum/consensus-specs/blob/v1.1.7/specs/merge/beacon-chain.md#testing
func get_initial_beacon_block*(state: capella.HashedBeaconState):
capella.TrustedSignedBeaconBlock =
# The genesis block is implicitly trusted
let message = capella.TrustedBeaconBlock(
slot: state.data.slot,
state_root: state.root)
# parent_root, randao_reveal, eth1_data, signature, and body automatically
# initialized to default values.
capella.TrustedSignedBeaconBlock(
message: message, root: hash_tree_root(message))
func get_initial_beacon_block*(state: ForkedHashedBeaconState):
ForkedTrustedSignedBeaconBlock =
withState(state):

View File

@ -976,3 +976,9 @@ func checkForkConsistency*(cfg: RuntimeConfig) =
assertForkEpochOrder(cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH)
assertForkEpochOrder(cfg.BELLATRIX_FORK_EPOCH, cfg.CAPELLA_FORK_EPOCH)
assertForkEpochOrder(cfg.CAPELLA_FORK_EPOCH, cfg.SHARDING_FORK_EPOCH)
# This is a readily/uniquely searchable token of where a false assertion is
# due to Capella implementation missing. checkForkConsistency() checks that
# Nimbus does not actually run any non-FAR_FUTURE_EPOCH Capella network, so
# such cases won't be hit.
const capellaImplementationMissing* = false

View File

@ -19,7 +19,6 @@ else:
{.push raises: [].}
import
stew/byteutils,
json_serialization,
ssz_serialization/types as sszTypes,
../digest,
@ -365,26 +364,6 @@ type
BoolReturnSuccessRPC = object
success*: bool
func fromHex*(T: typedesc[BloomLogs], s: string): T {.
raises: [Defect, ValueError].} =
hexToByteArray(s, result.data)
func fromHex*(T: typedesc[ExecutionAddress], s: string): T {.
raises: [Defect, ValueError].} =
hexToByteArray(s, result.data)
proc writeValue*(writer: var JsonWriter, value: ExecutionAddress) {.
raises: [Defect, IOError].} =
writer.writeValue to0xHex(value.data)
proc readValue*(reader: var JsonReader, value: var ExecutionAddress) {.
raises: [Defect, IOError, SerializationError].} =
try:
hexToByteArray(reader.readValue(string), value.data)
except ValueError:
raiseUnexpectedValue(reader,
"ExecutionAddress value should be a valid hex string")
func shortLog*(v: SomeBeaconBlock): auto =
(
slot: shortLog(v.slot),

View File

@ -959,6 +959,8 @@ proc readValue*[BlockType: ForkedBeaconBlock](
if res.isNone():
reader.raiseUnexpectedValue("Incorrect bellatrix block format")
value = ForkedBeaconBlock.init(res.get()).BlockType
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
proc readValue*[BlockType: Web3SignerForkedBeaconBlock](
reader: var JsonReader[RestJson],
@ -1012,6 +1014,8 @@ proc readValue*[BlockType: Web3SignerForkedBeaconBlock](
value = Web3SignerForkedBeaconBlock(
kind: BeaconBlockFork.Bellatrix,
bellatrixData: res.get())
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
proc writeValue*[
BlockType: Web3SignerForkedBeaconBlock|ForkedBeaconBlock|ForkedBlindedBeaconBlock](
@ -1035,6 +1039,8 @@ proc writeValue*[
of BeaconBlockFork.Bellatrix:
writer.writeField("version", forkIdentifier "bellatrix")
writer.writeField("data", value.bellatrixData)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
writer.endRecord()
## RestPublishedBeaconBlockBody
@ -1054,7 +1060,7 @@ proc readValue*(reader: var JsonReader[RestJson],
voluntary_exits: Option[
List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]]
sync_aggregate: Option[SyncAggregate]
execution_payload: Option[ExecutionPayload]
execution_payload: Option[bellatrix.ExecutionPayload]
for fieldName in readObjectFields(reader):
case fieldName
@ -1113,7 +1119,7 @@ proc readValue*(reader: var JsonReader[RestJson],
if execution_payload.isSome():
reader.raiseUnexpectedField("Multiple `execution_payload` fields found",
"RestPublishedBeaconBlockBody")
execution_payload = some(reader.readValue(ExecutionPayload))
execution_payload = some(reader.readValue(bellatrix.ExecutionPayload))
else:
unrecognizedFieldWarning()
@ -1188,6 +1194,8 @@ proc readValue*(reader: var JsonReader[RestJson],
execution_payload: execution_payload.get()
)
)
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
## RestPublishedBeaconBlock
proc readValue*(reader: var JsonReader[RestJson],
@ -1274,6 +1282,8 @@ proc readValue*(reader: var JsonReader[RestJson],
body: body.bellatrixBody
)
)
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
)
## RestPublishedSignedBeaconBlock
@ -1326,6 +1336,8 @@ proc readValue*(reader: var JsonReader[RestJson],
signature: signature.get()
)
)
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
)
## ForkedSignedBeaconBlock
@ -1402,6 +1414,8 @@ proc readValue*(reader: var JsonReader[RestJson],
if res.isNone():
reader.raiseUnexpectedValue("Incorrect bellatrix block format")
value = ForkedSignedBeaconBlock.init(res.get())
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
withBlck(value):
blck.root = hash_tree_root(blck.message)
@ -1419,6 +1433,8 @@ proc writeValue*(writer: var JsonWriter[RestJson],
of BeaconBlockFork.Bellatrix:
writer.writeField("version", "bellatrix")
writer.writeField("data", value.bellatrixData)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
writer.endRecord()
# ForkedHashedBeaconState is used where a `ForkedBeaconState` normally would
@ -1500,6 +1516,8 @@ proc readValue*(reader: var JsonReader[RestJson],
except SerializationError:
reader.raiseUnexpectedValue("Incorrect altair beacon state format")
toValue(bellatrixData)
of BeaconStateFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
proc writeValue*(writer: var JsonWriter[RestJson], value: ForkedHashedBeaconState)
{.raises: [IOError, Defect].} =
@ -1514,6 +1532,8 @@ proc writeValue*(writer: var JsonWriter[RestJson], value: ForkedHashedBeaconStat
of BeaconStateFork.Bellatrix:
writer.writeField("version", "bellatrix")
writer.writeField("data", value.bellatrixData.data)
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
writer.endRecord()
## Web3SignerRequest
@ -2403,6 +2423,8 @@ proc decodeBody*(
except CatchableError:
return err("Unexpected deserialization error")
ok(RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)))
of BeaconBlockFork.Capella:
return err($capellaImplementationMissing)
else:
return err("Unsupported or invalid content media type")

View File

@ -23,7 +23,9 @@ import
".."/datatypes/[phase0, altair, bellatrix],
".."/mev/bellatrix_mev
export forks, phase0, altair, bellatrix, bellatrix_mev
from ".."/datatypes/capella import BeaconBlockBody
export forks, phase0, altair, bellatrix, capella, bellatrix_mev
const
# https://github.com/ethereum/eth2.0-APIs/blob/master/apis/beacon/states/validator_balances.yaml#L17
@ -263,6 +265,7 @@ type
of BeaconBlockFork.Phase0: phase0Body*: phase0.BeaconBlockBody
of BeaconBlockFork.Altair: altairBody*: altair.BeaconBlockBody
of BeaconBlockFork.Bellatrix: bellatrixBody*: bellatrix.BeaconBlockBody
of BeaconBlockFork.Capella: cappellaBody*: capella.BeaconBlockBody
RestSpec* = object
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/presets/mainnet/phase0.yaml

View File

@ -18,6 +18,8 @@ import
./datatypes/[phase0, altair, bellatrix, capella],
./mev/bellatrix_mev
# TODO re-export capella, but for now it could cause knock-on effects, so stage
# it sequentially
export
extras, block_id, phase0, altair, bellatrix, eth2_merkleization,
eth2_ssz_serialization, presets
@ -42,7 +44,8 @@ type
BeaconStateFork* {.pure.} = enum
Phase0,
Altair,
Bellatrix
Bellatrix,
Capella
ForkyBeaconState* =
phase0.BeaconState |
@ -53,18 +56,21 @@ type
ForkyHashedBeaconState* =
phase0.HashedBeaconState |
altair.HashedBeaconState |
bellatrix.HashedBeaconState
bellatrix.HashedBeaconState |
capella.HashedBeaconState
ForkedHashedBeaconState* = object
case kind*: BeaconStateFork
of BeaconStateFork.Phase0: phase0Data*: phase0.HashedBeaconState
of BeaconStateFork.Altair: altairData*: altair.HashedBeaconState
of BeaconStateFork.Bellatrix: bellatrixData*: bellatrix.HashedBeaconState
of BeaconStateFork.Capella: capellaData*: capella.HashedBeaconState
BeaconBlockFork* {.pure.} = enum
Phase0
Altair
Bellatrix
Bellatrix,
Capella
ForkyBeaconBlockBody* =
phase0.BeaconBlockBody |
@ -95,12 +101,14 @@ type
ForkySigVerifiedBeaconBlock* =
phase0.SigVerifiedBeaconBlock |
altair.SigVerifiedBeaconBlock |
bellatrix.SigVerifiedBeaconBlock
bellatrix.SigVerifiedBeaconBlock |
capella.SigVerifiedBeaconBlock
ForkyTrustedBeaconBlock* =
phase0.TrustedBeaconBlock |
altair.TrustedBeaconBlock |
bellatrix.TrustedBeaconBlock
bellatrix.TrustedBeaconBlock |
capella.TrustedBeaconBlock
SomeForkyBeaconBlock* =
ForkyBeaconBlock |
@ -112,62 +120,73 @@ type
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.BeaconBlock
Web3SignerForkedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: BeaconBlockHeader
of BeaconBlockFork.Capella: capellaData*: BeaconBlockHeader
ForkedBlindedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: BlindedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: BlindedBeaconBlock
ForkedTrustedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.TrustedBeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.TrustedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.TrustedBeaconBlock
ForkySignedBeaconBlock* =
phase0.SignedBeaconBlock |
altair.SignedBeaconBlock |
bellatrix.SignedBeaconBlock
bellatrix.SignedBeaconBlock |
capella.SignedBeaconBlock
ForkedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.SignedBeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.SignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.SignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.SignedBeaconBlock
ForkySigVerifiedSignedBeaconBlock* =
phase0.SigVerifiedSignedBeaconBlock |
altair.SigVerifiedSignedBeaconBlock |
bellatrix.SigVerifiedSignedBeaconBlock
bellatrix.SigVerifiedSignedBeaconBlock |
capella.SigVerifiedSignedBeaconBlock
ForkyMsgTrustedSignedBeaconBlock* =
phase0.MsgTrustedSignedBeaconBlock |
altair.MsgTrustedSignedBeaconBlock |
bellatrix.MsgTrustedSignedBeaconBlock
bellatrix.MsgTrustedSignedBeaconBlock |
capella.MsgTrustedSignedBeaconBlock
ForkyTrustedSignedBeaconBlock* =
phase0.TrustedSignedBeaconBlock |
altair.TrustedSignedBeaconBlock |
bellatrix.TrustedSignedBeaconBlock
bellatrix.TrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock
ForkedMsgTrustedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.MsgTrustedSignedBeaconBlock
ForkedTrustedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0: phase0Data*: phase0.TrustedSignedBeaconBlock
of BeaconBlockFork.Altair: altairData*: altair.TrustedSignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedSignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.TrustedSignedBeaconBlock
SomeForkySignedBeaconBlock* =
ForkySignedBeaconBlock |
@ -202,6 +221,9 @@ template toFork*[T: altair.BeaconState | altair.HashedBeaconState](
template toFork*[T: bellatrix.BeaconState | bellatrix.HashedBeaconState](
t: type T): BeaconStateFork =
BeaconStateFork.Bellatrix
template toFork*[T: capella.BeaconState | capella.HashedBeaconState](
t: type T): BeaconStateFork =
BeaconStateFork.Capella
# TODO these cause stack overflows due to large temporaries getting allocated
# template init*(T: type ForkedHashedBeaconState, data: phase0.HashedBeaconState): T =
@ -231,6 +253,8 @@ template init*(T: type ForkedSignedBeaconBlock, blck: altair.SignedBeaconBlock):
T(kind: BeaconBlockFork.Altair, altairData: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: bellatrix.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: capella.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
blockRoot: Eth2Digest, signature: ValidatorSig): T =
@ -250,20 +274,29 @@ template init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
bellatrixData: bellatrix.SignedBeaconBlock(message: forked.bellatrixData,
root: blockRoot,
signature: signature))
of BeaconBlockFork.Capella:
T(kind: BeaconBlockFork.Capella,
capellaData: capella.SignedBeaconBlock(message: forked.capellaData,
root: blockRoot,
signature: signature))
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: phase0.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: altair.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Altair, altairData: blck)
T(kind: BeaconBlockFork.Altair, altairData: blck)
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: bellatrix.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: capella.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: phase0.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: altair.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Altair, altairData: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: bellatrix.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: capella.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template toString*(kind: BeaconBlockFork): string =
case kind
@ -273,6 +306,8 @@ template toString*(kind: BeaconBlockFork): string =
"altair"
of BeaconBlockFork.Bellatrix:
"bellatrix"
of BeaconBlockFork.Capella:
"capella"
template toString*(kind: BeaconStateFork): string =
case kind
@ -282,6 +317,8 @@ template toString*(kind: BeaconStateFork): string =
"altair"
of BeaconStateFork.Bellatrix:
"bellatrix"
of BeaconStateFork.Capella:
"capella"
template toFork*[T:
phase0.BeaconBlock |
@ -310,6 +347,15 @@ template toFork*[T:
bellatrix.TrustedSignedBeaconBlock](
t: type T): BeaconBlockFork =
BeaconBlockFork.Bellatrix
template toFork*[T:
capella.BeaconBlock |
capella.SignedBeaconBlock |
capella.TrustedBeaconBlock |
capella.SigVerifiedSignedBeaconBlock |
capella.MsgTrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock](
t: type T): BeaconBlockFork =
BeaconBlockFork.Capella
template init*(T: type ForkedEpochInfo, info: phase0.EpochInfo): T =
T(kind: EpochInfoFork.Phase0, phase0Data: info)
@ -318,6 +364,10 @@ template init*(T: type ForkedEpochInfo, info: altair.EpochInfo): T =
template withState*(x: ForkedHashedBeaconState, body: untyped): untyped =
case x.kind
of BeaconStateFork.Capella:
const stateFork {.inject, used.} = BeaconStateFork.Capella
template forkyState: untyped {.inject, used.} = x.capellaData
body
of BeaconStateFork.Bellatrix:
const stateFork {.inject, used.} = BeaconStateFork.Bellatrix
template forkyState: untyped {.inject, used.} = x.bellatrixData
@ -349,8 +399,8 @@ template withEpochInfo*(
body
template withEpochInfo*(
state: altair.BeaconState | bellatrix.BeaconState, x: var ForkedEpochInfo,
body: untyped): untyped =
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState,
x: var ForkedEpochInfo, body: untyped): untyped =
x.kind = EpochInfoFork.Altair
template info: untyped {.inject.} = x.altairData
body
@ -358,6 +408,8 @@ template withEpochInfo*(
func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
if tgt.kind == src.kind:
case tgt.kind
of BeaconStateFork.Capella:
assign(tgt.capellaData, src.capellaData):
of BeaconStateFork.Bellatrix:
assign(tgt.bellatrixData, src.bellatrixData):
of BeaconStateFork.Altair:
@ -376,6 +428,7 @@ template getStateField*(x: ForkedHashedBeaconState, y: untyped): untyped =
# ```
# Without `unsafeAddr`, the `validators` list would be copied to a temporary variable.
(case x.kind
of BeaconStateFork.Capella: unsafeAddr x.capellaData.data.y
of BeaconStateFork.Bellatrix: unsafeAddr x.bellatrixData.data.y
of BeaconStateFork.Altair: unsafeAddr x.altairData.data.y
of BeaconStateFork.Phase0: unsafeAddr x.phase0Data.data.y)[]
@ -389,23 +442,28 @@ func setStateRoot*(x: var ForkedHashedBeaconState, root: Eth2Digest) =
func stateForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): BeaconStateFork =
## Return the current fork for the given epoch.
static:
doAssert BeaconStateFork.Capella > BeaconStateFork.Bellatrix
doAssert BeaconStateFork.Bellatrix > BeaconStateFork.Altair
doAssert BeaconStateFork.Altair > BeaconStateFork.Phase0
doAssert GENESIS_EPOCH == 0
if epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconStateFork.Bellatrix
if epoch >= cfg.CAPELLA_FORK_EPOCH: BeaconStateFork.Capella
elif epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconStateFork.Bellatrix
elif epoch >= cfg.ALTAIR_FORK_EPOCH: BeaconStateFork.Altair
else: BeaconStateFork.Phase0
func blockForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): BeaconBlockFork =
## Return the current fork for the given epoch.
if epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconBlockFork.Bellatrix
if epoch >= cfg.CAPELLA_FORK_EPOCH: BeaconBlockFork.Capella
elif epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconBlockFork.Bellatrix
elif epoch >= cfg.ALTAIR_FORK_EPOCH: BeaconBlockFork.Altair
else: BeaconBlockFork.Phase0
func stateForkForDigest*(
forkDigests: ForkDigests, forkDigest: ForkDigest): Opt[BeaconStateFork] =
if forkDigest == forkDigests.bellatrix:
if forkDigest == forkDigests.capella:
ok BeaconStateFork.Capella
elif forkDigest == forkDigests.bellatrix:
ok BeaconStateFork.Bellatrix
elif forkDigest == forkDigests.altair:
ok BeaconStateFork.Altair
@ -417,6 +475,8 @@ func stateForkForDigest*(
func atStateFork*(
forkDigests: ForkDigests, stateFork: BeaconStateFork): ForkDigest =
case stateFork
of BeaconStateFork.Capella:
forkDigests.capella
of BeaconStateFork.Bellatrix:
forkDigests.bellatrix
of BeaconStateFork.Altair:
@ -482,6 +542,10 @@ template withBlck*(
const stateFork {.inject, used.} = BeaconStateFork.Bellatrix
template blck: untyped {.inject.} = x.bellatrixData
body
of BeaconBlockFork.Capella:
const stateFork {.inject, used.} = BeaconStateFork.Capella
template blck: untyped {.inject.} = x.capellaData
body
func proposer_index*(x: ForkedBeaconBlock): uint64 =
withBlck(x): blck.proposer_index
@ -499,7 +563,8 @@ template getForkedBlockField*(
(case x.kind
of BeaconBlockFork.Phase0: unsafeAddr x.phase0Data.message.y
of BeaconBlockFork.Altair: unsafeAddr x.altairData.message.y
of BeaconBlockFork.Bellatrix: unsafeAddr x.bellatrixData.message.y)[]
of BeaconBlockFork.Bellatrix: unsafeAddr x.bellatrixData.message.y
of BeaconBlockFork.Capella: unsafeAddr x.capellaData.message.y)[]
template signature*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock): ValidatorSig =
@ -538,6 +603,11 @@ template withStateAndBlck*(
ForkedTrustedSignedBeaconBlock,
body: untyped): untyped =
case s.kind
of BeaconStateFork.Capella:
const stateFork {.inject.} = BeaconStateFork.Capella
template forkyState: untyped {.inject.} = s.capellaData
template blck: untyped {.inject.} = b.capellaData
body
of BeaconStateFork.Bellatrix:
const stateFork {.inject.} = BeaconStateFork.Bellatrix
template forkyState: untyped {.inject.} = s.bellatrixData
@ -588,28 +658,35 @@ func altairFork*(cfg: RuntimeConfig): Fork =
epoch: cfg.ALTAIR_FORK_EPOCH)
func bellatrixFork*(cfg: RuntimeConfig): Fork =
# TODO in theory, the altair + merge forks could be in same epoch, so the
# previous fork version would be the GENESIS_FORK_VERSION
Fork(
previous_version: cfg.ALTAIR_FORK_VERSION,
current_version: cfg.BELLATRIX_FORK_VERSION,
epoch: cfg.BELLATRIX_FORK_EPOCH)
func capellaFork*(cfg: RuntimeConfig): Fork =
Fork(
previous_version: cfg.BELLATRIX_FORK_VERSION,
current_version: cfg.CAPELLA_FORK_VERSION,
epoch: cfg.CAPELLA_FORK_EPOCH)
func forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
case cfg.stateForkAtEpoch(epoch)
of BeaconStateFork.Capella: cfg.capellaFork
of BeaconStateFork.Bellatrix: cfg.bellatrixFork
of BeaconStateFork.Altair: cfg.altairFork
of BeaconStateFork.Phase0: cfg.genesisFork
func forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
case cfg.stateForkAtEpoch(epoch)
of BeaconStateFork.Capella: cfg.CAPELLA_FORK_VERSION
of BeaconStateFork.Bellatrix: cfg.BELLATRIX_FORK_VERSION
of BeaconStateFork.Altair: cfg.ALTAIR_FORK_VERSION
of BeaconStateFork.Phase0: cfg.GENESIS_FORK_VERSION
func nextForkEpochAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Epoch =
case cfg.stateForkAtEpoch(epoch)
of BeaconStateFork.Bellatrix: FAR_FUTURE_EPOCH
of BeaconStateFork.Capella: FAR_FUTURE_EPOCH
of BeaconStateFork.Bellatrix: cfg.CAPELLA_FORK_EPOCH
of BeaconStateFork.Altair: cfg.BELLATRIX_FORK_EPOCH
of BeaconStateFork.Phase0: cfg.ALTAIR_FORK_EPOCH
@ -676,6 +753,7 @@ func toBeaconBlockFork*(fork: BeaconStateFork): BeaconBlockFork =
of BeaconStateFork.Phase0: BeaconBlockFork.Phase0
of BeaconStateFork.Altair: BeaconBlockFork.Altair
of BeaconStateFork.Bellatrix: BeaconBlockFork.Bellatrix
of BeaconStateFork.Capella: BeaconBlockFork.Capella
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#compute_fork_data_root
func compute_fork_data_root*(current_version: Version,

View File

@ -581,3 +581,5 @@ proc makeBeaconBlock*(
of BeaconStateFork.Phase0: makeBeaconBlock(phase0)
of BeaconStateFork.Altair: makeBeaconBlock(altair)
of BeaconStateFork.Bellatrix: makeBeaconBlock(bellatrix)
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing

View File

@ -715,3 +715,12 @@ proc process_block*(
state, blck.body.sync_aggregate, total_active_balance, cache)
ok()
# TODO workaround for https://github.com/nim-lang/Nim/issues/18095
type SomeCapellaBlock =
capella.BeaconBlock | capella.SigVerifiedBeaconBlock | capella.TrustedBeaconBlock
proc process_block*(
cfg: RuntimeConfig,
state: var capella.BeaconState, blck: SomeCapellaBlock,
flags: UpdateFlags, cache: var StateCache): Result[void, cstring]=
raiseAssert $capellaImplementationMissing

View File

@ -1223,3 +1223,51 @@ proc process_epoch*(
process_sync_committee_updates(state) # [New in Altair]
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#epoch-processing
proc process_epoch*(
cfg: RuntimeConfig, state: var capella.BeaconState,
flags: UpdateFlags, cache: var StateCache, info: var altair.EpochInfo):
Result[void, cstring] =
let currentEpoch = get_current_epoch(state)
trace "process_epoch",
current_epoch = currentEpoch
info.init(state)
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#justification-and-finalization
process_justification_and_finalization(state, info.balances, flags)
# state.slot hasn't been incremented yet.
if strictVerification in flags and currentEpoch >= 2:
doAssert state.current_justified_checkpoint.epoch + 2 >= currentEpoch
if strictVerification in flags and currentEpoch >= 3:
# Rule 2/3/4 finalization results in the most pessimal case. The other
# three finalization rules finalize more quickly as long as the any of
# the finalization rules triggered.
doAssert state.finalized_checkpoint.epoch + 3 >= currentEpoch
process_inactivity_updates(cfg, state, info) # [New in Altair]
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#process_rewards_and_penalties
process_rewards_and_penalties(cfg, state, info)
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#registry-updates
? process_registry_updates(cfg, state, cache)
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/phase0/beacon-chain.md#slashings
process_slashings(state, info.balances.current_epoch)
process_eth1_data_reset(state)
process_effective_balance_updates(state)
process_slashings_reset(state)
process_randao_mixes_reset(state)
process_historical_roots_update(state)
process_participation_flag_updates(state)
process_sync_committee_updates(state)
process_full_withdrawals(state) # [New in Capella]
process_partial_withdrawals(state) # [New in Capella]
ok()

View File

@ -1685,6 +1685,8 @@ proc publishBlock*(
publishBlock(it, data.altairData)
of BeaconBlockFork.Bellatrix:
publishBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()
@ -1732,6 +1734,8 @@ proc publishBlock*(
publishBlock(it, data.altairData)
of BeaconBlockFork.Bellatrix:
publishBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()

View File

@ -350,7 +350,9 @@ proc getExecutionPayload[T](
template empty_execution_payload(): auto =
withState(proposalState[]):
when stateFork >= BeaconStateFork.Bellatrix:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Bellatrix:
build_empty_execution_payload(forkyState.data)
else:
default(T)
@ -434,7 +436,7 @@ proc makeBeaconBlockForHeadAndSlot*(
validator_index: ValidatorIndex, graffiti: GraffitiBytes, head: BlockRef,
slot: Slot,
skip_randao_verification_bool: bool = false,
execution_payload: Opt[ExecutionPayload] = Opt.none(ExecutionPayload),
execution_payload: Opt[bellatrix.ExecutionPayload] = Opt.none(bellatrix.ExecutionPayload),
transactions_root: Opt[Eth2Digest] = Opt.none(Eth2Digest),
execution_payload_root: Opt[Eth2Digest] = Opt.none(Eth2Digest)):
Future[ForkedBlockResult] {.async.} =
@ -443,7 +445,8 @@ proc makeBeaconBlockForHeadAndSlot*(
cache = StateCache()
# Execution payload handling will need a review post-Bellatrix
static: doAssert high(BeaconStateFork) == BeaconStateFork.Bellatrix
if slot.epoch >= node.dag.cfg.CAPELLA_FORK_EPOCH:
raiseAssert $capellaImplementationMissing
let
# The clearance state already typically sits at the right slot per
@ -453,14 +456,14 @@ proc makeBeaconBlockForHeadAndSlot*(
return err($error)
payloadFut =
if executionPayload.isSome:
let fut = newFuture[Opt[ExecutionPayload]]("given-payload")
let fut = newFuture[Opt[bellatrix.ExecutionPayload]]("given-payload")
fut.complete(executionPayload)
fut
elif slot.epoch < node.dag.cfg.BELLATRIX_FORK_EPOCH or
not (
is_merge_transition_complete(state[]) or
((not node.eth1Monitor.isNil) and node.eth1Monitor.ttdReached)):
let fut = newFuture[Opt[ExecutionPayload]]("empty-payload")
let fut = newFuture[Opt[bellatrix.ExecutionPayload]]("empty-payload")
# https://github.com/nim-lang/Nim/issues/19802
fut.complete(Opt.some(default(bellatrix.ExecutionPayload)))
fut
@ -524,7 +527,7 @@ proc makeBeaconBlockForHeadAndSlot*(
proc getBlindedExecutionPayload(
node: BeaconNode, slot: Slot, executionBlockRoot: Eth2Digest,
pubkey: ValidatorPubKey):
Future[Result[ExecutionPayloadHeader, string]] {.async.} =
Future[Result[bellatrix.ExecutionPayloadHeader, string]] {.async.} =
if node.payloadBuilderRestClient.isNil:
return err "getBlindedExecutionPayload: nil REST client"
@ -568,8 +571,7 @@ macro copyFields(
func constructSignableBlindedBlock[T](
forkedBlock: ForkedBeaconBlock,
executionPayloadHeader: ExecutionPayloadHeader): T =
static: doAssert high(BeaconStateFork) == BeaconStateFork.Bellatrix
executionPayloadHeader: bellatrix.ExecutionPayloadHeader): T =
const
blckFields = getFieldNames(typeof(forkedBlock.bellatrixData))
blckBodyFields = getFieldNames(typeof(forkedBlock.bellatrixData.body))
@ -586,8 +588,7 @@ func constructSignableBlindedBlock[T](
func constructPlainBlindedBlock[T](
forkedBlock: ForkedBeaconBlock,
executionPayloadHeader: ExecutionPayloadHeader): T =
static: doAssert high(BeaconStateFork) == BeaconStateFork.Bellatrix
executionPayloadHeader: bellatrix.ExecutionPayloadHeader): T =
const
blckFields = getFieldNames(typeof(forkedBlock.bellatrixData))
blckBodyFields = getFieldNames(typeof(forkedBlock.bellatrixData.body))
@ -639,7 +640,7 @@ proc blindedBlockCheckSlashingAndSign[T](
proc getBlindedBeaconBlock[T](
node: BeaconNode, slot: Slot, validator: AttachedValidator,
validator_index: ValidatorIndex, forkedBlock: ForkedBeaconBlock,
executionPayloadHeader: ExecutionPayloadHeader):
executionPayloadHeader: bellatrix.ExecutionPayloadHeader):
Future[Result[T, string]] {.async.} =
return await blindedBlockCheckSlashingAndSign(
node, slot, validator, validator_index, constructSignableBlindedBlock[T](
@ -648,7 +649,7 @@ proc getBlindedBeaconBlock[T](
proc getBlindedBlockParts(
node: BeaconNode, head: BlockRef, validator: AttachedValidator,
slot: Slot, randao: ValidatorSig, validator_index: ValidatorIndex):
Future[Result[(ExecutionPayloadHeader, ForkedBeaconBlock), string]]
Future[Result[(bellatrix.ExecutionPayloadHeader, ForkedBeaconBlock), string]]
{.async.} =
let
executionBlockRoot = node.dag.loadExecutionBlockRoot(head)
@ -658,13 +659,13 @@ proc getBlindedBlockParts(
node.getBlindedExecutionPayload(
slot, executionBlockRoot, validator.pubkey),
BUILDER_PROPOSAL_DELAY_TOLERANCE):
Result[ExecutionPayloadHeader, string].err(
Result[bellatrix.ExecutionPayloadHeader, string].err(
"getBlindedExecutionPayload timed out")
except RestDecodingError as exc:
Result[ExecutionPayloadHeader, string].err(
Result[bellatrix.ExecutionPayloadHeader, string].err(
"getBlindedExecutionPayload REST decoding error")
except CatchableError as exc:
Result[ExecutionPayloadHeader, string].err(
Result[bellatrix.ExecutionPayloadHeader, string].err(
"getBlindedExecutionPayload error")
if executionPayloadHeader.isErr:
@ -680,10 +681,10 @@ proc getBlindedBlockParts(
# processing does not work directly using blinded blocks, fix up transactions
# root after running the state transition function on an otherwise equivalent
# non-blinded block without transactions.
var shimExecutionPayload: ExecutionPayload
var shimExecutionPayload: bellatrix.ExecutionPayload
copyFields(
shimExecutionPayload, executionPayloadHeader.get,
getFieldNames(ExecutionPayloadHeader))
getFieldNames(bellatrix.ExecutionPayloadHeader))
let newBlock = await makeBeaconBlockForHeadAndSlot(
node, randao, validator_index, node.graffitiBytes, head, slot,
@ -849,6 +850,9 @@ proc makeBlindedBeaconBlockForHeadAndSlot*(
return ok constructPlainBlindedBlock[BlindedBeaconBlock](
forkedBlck, executionPayloadHeader)
# TODO once forks re-exports these, use that instead
from ../spec/datatypes/capella import BeaconBlock
proc proposeBlock(node: BeaconNode,
validator: AttachedValidator,
validator_index: ValidatorIndex,
@ -941,6 +945,9 @@ proc proposeBlock(node: BeaconNode,
elif blck is bellatrix.BeaconBlock:
bellatrix.SignedBeaconBlock(
message: blck, signature: signature, root: blockRoot)
elif blck is capella.BeaconBlock:
capella.SignedBeaconBlock(
message: blck, signature: signature, root: blockRoot)
else:
static: doAssert "Unknown SignedBeaconBlock type"
newBlockRef =

View File

@ -11,6 +11,9 @@ import
../spec/[beaconstate, forks, helpers],
../beacon_clock
# TODO when forks re-exports capella, drop this
from ../spec/datatypes/capella import shortLog
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:

View File

@ -305,6 +305,8 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
Web3SignerForkedBeaconBlock(
kind: BeaconBlockFork.Bellatrix,
bellatrixData: blck.bellatrixData.toBeaconBlockHeader)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
request = Web3SignerRequest.init(
fork, genesis_validators_root, web3SignerBlock)

View File

@ -84,6 +84,7 @@ template saveSSZFile(filename: string, value: ForkedHashedBeaconState) =
of BeaconStateFork.Phase0: SSZ.saveFile(filename, value.phase0Data.data)
of BeaconStateFork.Altair: SSZ.saveFile(filename, value.altairData.data)
of BeaconStateFork.Bellatrix: SSZ.saveFile(filename, value.bellatrixData.data)
of BeaconStateFork.Capella: SSZ.saveFile(filename, value.capellaData.data)
proc loadFile(filename: string, T: type): T =
let

View File

@ -19,6 +19,8 @@ import
signatures],
../beacon_chain/consensus_object_pools/blockchain_dag
from ../beacon_chain/spec/datatypes/capella import BeaconState
type
RewardsAndPenalties* = object
source_outcome*: int64
@ -266,7 +268,7 @@ proc collectEpochRewardsAndPenalties*(
proc collectEpochRewardsAndPenalties*(
rewardsAndPenalties: var seq[RewardsAndPenalties],
state: var (altair.BeaconState | bellatrix.BeaconState),
state: var (altair.BeaconState | bellatrix.BeaconState | capella.BeaconState),
cache: var StateCache, cfg: RuntimeConfig, flags: UpdateFlags) =
if get_current_epoch(state) == GENESIS_EPOCH:
return

View File

@ -252,6 +252,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
of BeaconBlockFork.Bellatrix:
blocks[2].add dag.db.getBlock(
blck.root, bellatrix.TrustedSignedBeaconBlock).get()
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
let stateData = newClone(dag.headState)
@ -316,12 +318,15 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
of BeaconStateFork.Bellatrix:
doAssert dbBenchmark.getState(
forkyState.root, loadedState[2][].data, noRollback)
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
if forkyState.data.slot.epoch mod 16 == 0:
let loadedRoot = case stateFork
of BeaconStateFork.Phase0: hash_tree_root(loadedState[0][].data)
of BeaconStateFork.Altair: hash_tree_root(loadedState[1][].data)
of BeaconStateFork.Bellatrix: hash_tree_root(loadedState[2][].data)
of BeaconStateFork.Capella: raiseAssert $capellaImplementationMissing
doAssert hash_tree_root(forkyState.data) == loadedRoot
processBlocks(blocks[0])

View File

@ -401,6 +401,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
if blockRatio > 0.0:
withTimer(timers[t]):
case dag.cfg.stateForkAtEpoch(slot.epoch)
of BeaconStateFork.Capella: raiseAssert $capellaImplementationMissing
of BeaconStateFork.Bellatrix: proposeBellatrixBlock(slot)
of BeaconStateFork.Altair: proposeAltairBlock(slot)
of BeaconStateFork.Phase0: proposePhase0Block(slot)

View File

@ -159,7 +159,7 @@ cli do(validatorsDir: string, secretsDir: string,
@[],
BeaconBlockExits(),
syncAggregate,
default(ExecutionPayload),
default(bellatrix.ExecutionPayload),
noRollback,
cache).get()
@ -191,6 +191,8 @@ cli do(validatorsDir: string, secretsDir: string,
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
notice "Block proposed", message, blockRoot
aggregates.setLen(0)

View File

@ -44,6 +44,10 @@ func readValue*(r: var JsonReader, a: var seq[byte]) =
func genesisTestRuntimeConfig*(stateFork: BeaconStateFork): RuntimeConfig =
var res = defaultRuntimeConfig
case stateFork
of BeaconStateFork.Capella:
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
of BeaconStateFork.Bellatrix:
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
@ -120,6 +124,8 @@ proc loadForkedState*(
# prevent temporaries created by case objects
let forkedState = new ForkedHashedBeaconState
case fork
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
of BeaconStateFork.Bellatrix:
let state = newClone(parseTest(path, SSZ, bellatrix.BeaconState))
forkedState.kind = BeaconStateFork.Bellatrix

View File

@ -149,6 +149,8 @@ proc loadOps(path: string, fork: BeaconStateFork): seq[Operation] =
)
result.add Operation(kind: opOnBlock,
blck: ForkedSignedBeaconBlock.init(blck))
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif step.hasKey"attester_slashing":
let filename = step["attester_slashing"].getStr()
let attesterSlashing = parseTest(
@ -297,6 +299,8 @@ proc doRunTest(path: string, fork: BeaconStateFork) =
let stores =
case fork
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
of BeaconStateFork.Bellatrix:
initialLoad(path, db, bellatrix.BeaconState, bellatrix.BeaconBlock)
of BeaconStateFork.Altair:
@ -328,11 +332,14 @@ proc doRunTest(path: string, fork: BeaconStateFork) =
doAssert status.isOk == step.valid
of opOnBlock:
withBlck(step.blck):
let status = stepOnBlock(
stores.dag, stores.fkChoice,
verifier, state[], stateCache,
blck, time, invalidatedRoots)
doAssert status.isOk == step.valid
when stateFork != BeaconStateFork.Capella:
let status = stepOnBlock(
stores.dag, stores.fkChoice,
verifier, state[], stateCache,
blck, time, invalidatedRoots)
doAssert status.isOk == step.valid
else:
raiseAssert $capellaImplementationMissing
of opOnAttesterSlashing:
let indices =
check_attester_slashing(state[], step.attesterSlashing, flags = {})
@ -369,6 +376,8 @@ proc runTest(testType: static[string], path: string, fork: BeaconStateFork) =
else:
if os.splitPath(path).tail in SKIP:
skip()
elif capellaImplementationMissing or path.contains("/capella/"):
skip()
else:
doRunTest(path, fork)
@ -380,9 +389,6 @@ template fcSuite(suiteName: static[string], testPathElem: static[string]) =
if kind != pcDir or not dirExists(testsPath):
continue
let fork = forkForPathComponent(path).valueOr:
if path.contains("capella"):
# TODO forkForPathComponent relies on ForkedFoo
continue
raiseAssert "Unknown test fork: " & testsPath
for kind, path in walkDir(testsPath, relative = true, checkDir = true):
let basePath = testsPath/path/"pyspec_tests"

View File

@ -23,6 +23,10 @@ import
proc runTest(path: string, fork: BeaconStateFork) =
test "Light client - Single merkle proof - " & path.relativePath(SszTestsDir):
if capellaImplementationMissing or fork == BeaconStateFork.Capella:
skip()
return
type
TestProof = object
leaf: string
@ -52,8 +56,6 @@ proc runTest(path: string, fork: BeaconStateFork) =
get_subtree_index(proof.leaf_index),
forkyState.root)
from strutils import contains
suite "EF - Light client - Single merkle proof" & preset():
const presetPath = SszTestsDir/const_preset
for kind, path in walkDir(presetPath, relative = true, checkDir = true):
@ -62,9 +64,6 @@ suite "EF - Light client - Single merkle proof" & preset():
continue
let
fork = forkForPathComponent(path).valueOr:
if path.contains("capella"):
# TODO forkForPathComponent relies on ForkedFoo
continue
raiseAssert "Unknown test fork: " & testsPath
basePath = testsPath/"pyspec_tests"
for kind, path in walkDir(basePath, relative = true, checkDir = true):

View File

@ -207,6 +207,8 @@ suite "Gossip validation - Extra": # Not based on preset config
of BeaconBlockFork.Bellatrix:
const nilCallback = OnBellatrixBlockAdded(nil)
dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
check: added.isOk()
dag.updateHead(added[], quarantine[])
dag

View File

@ -67,6 +67,8 @@ suite "Light client" & preset():
of BeaconBlockFork.Bellatrix:
const nilCallback = OnBellatrixBlockAdded(nil)
dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
check: added.isOk()
dag.updateHead(added[], quarantine)

View File

@ -52,6 +52,8 @@ suite "Light client processor" & preset():
of BeaconBlockFork.Bellatrix:
const nilCallback = OnBellatrixBlockAdded(nil)
dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
doAssert added.isOk()
dag.updateHead(added[], quarantine[])

View File

@ -138,7 +138,9 @@ proc addTestBlock*(
let execution_payload =
withState(state):
when stateFork >= BeaconStateFork.Bellatrix:
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Bellatrix:
# Merge shortly after Bellatrix
if forkyState.data.slot >
cfg.BELLATRIX_FORK_EPOCH * SLOTS_PER_EPOCH + 10:

View File

@ -11,6 +11,7 @@ else:
{.push raises: [].}
import
chronicles,
std/options,
./mocking/mock_deposits,
./helpers/math_helpers,