refactor `makeBeaconBlock`; some capella support for `ncli_db` and `wss_sim` (#4321)

This commit is contained in:
tersec 2022-11-11 14:37:43 +00:00 committed by GitHub
parent 93714756d7
commit b3f6be71d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 229 additions and 213 deletions

View File

@ -673,15 +673,9 @@ proc close*(db: BeaconChainDB) =
discard db.summaries.close()
discard db.stateDiffs.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:
# The scaffolding currently creates nil databases
if (capellaImplementationMissing == capellaImplementationMissing) and
not (kv.isNil):
discard kv.close()
discard db.keyValues.close()
@ -790,18 +784,12 @@ proc putStateDiff*(db: BeaconChainDB, root: Eth2Digest, value: BeaconStateDiff)
proc delBlock*(db: BeaconChainDB, key: Eth2Digest) =
db.withManyWrites:
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:
# 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) =

View File

@ -146,9 +146,7 @@ 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.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
when stateFork >= BeaconStateFork.Altair:
forkyState.data.compute_unrealized_finality()
else:
var cache: StateCache

View File

@ -24,10 +24,12 @@ logScope: topics = "chaindag_lc"
type
HashedBeaconStateWithSyncCommittee =
capella.HashedBeaconState |
bellatrix.HashedBeaconState |
altair.HashedBeaconState
TrustedSignedBeaconBlockWithSyncAggregate =
capella.TrustedSignedBeaconBlock |
bellatrix.TrustedSignedBeaconBlock |
altair.TrustedSignedBeaconBlock
@ -217,6 +219,8 @@ proc initLightClientBootstrapForPeriod(
dag.lcDataStore.db.putCurrentSyncCommitteeBranch(bid.slot, branch)
res
from ../spec/datatypes/capella import asSigned
proc initLightClientUpdateForPeriod(
dag: ChainDAGRef, period: SyncCommitteePeriod): Opt[void] =
## Compute and cache the best `LightClientUpdate` within a given
@ -383,9 +387,8 @@ proc initLightClientUpdateForPeriod(
dag.handleUnexpectedLightClientError(signatureBid.slot)
return err()
withBlck(bdata):
when stateFork >= BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
elif stateFork >= BeaconStateFork.Altair:
static: doAssert high(BeaconStateFork) == BeaconStateFork.Capella
when stateFork >= BeaconStateFork.Altair:
update.sync_aggregate = blck.asSigned().message.body.sync_aggregate
else: raiseAssert "Unreachable"
update.signature_slot = signatureBid.slot
@ -721,7 +724,8 @@ proc processNewBlockForLightClient*(
return
when signedBlock is capella.TrustedSignedBeaconBlock:
raiseAssert $capellaImplementationMissing
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)

View File

@ -289,11 +289,8 @@ proc getBlockOptimistic*(node: BeaconNode,
case blck.kind
of BeaconBlockFork.Phase0, BeaconBlockFork.Altair:
some[bool](false)
of BeaconBlockFork.Bellatrix:
of BeaconBlockFork.Bellatrix, BeaconBlockFork.Capella:
some[bool](node.dag.is_optimistic(blck.root))
of BeaconBlockFork.Capella:
if true: raiseAssert $capellaImplementationMissing
none[bool]()
else:
none[bool]()

View File

@ -90,7 +90,7 @@ func verifyStateRoot(
type
RollbackProc* = proc() {.gcsafe, noSideEffect, raises: [Defect].}
RollbackHashedProc[T] =
RollbackHashedProc*[T] =
proc(state: var T) {.gcsafe, noSideEffect, raises: [Defect].}
RollbackForkedHashedProc* = RollbackHashedProc[ForkedHashedBeaconState]
@ -316,7 +316,7 @@ proc state_transition*(
cfg, state, signedBlock, cache, flags, rollback)
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/phase0/validator.md#preparing-for-a-beaconblock
template partialBeaconBlock(
template partialBeaconBlock*(
cfg: RuntimeConfig,
state: var phase0.HashedBeaconState,
proposer_index: ValidatorIndex,
@ -342,51 +342,8 @@ template partialBeaconBlock(
deposits: List[Deposit, Limit MAX_DEPOSITS](deposits),
voluntary_exits: exits.voluntary_exits))
proc makeBeaconBlock*(
cfg: RuntimeConfig,
state: var phase0.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[phase0.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[phase0.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
# https://github.com/ethereum/consensus-specs/blob/v1.2.0/specs/altair/validator.md#preparing-a-beaconblock
template partialBeaconBlock(
template partialBeaconBlock*(
cfg: RuntimeConfig,
state: var altair.HashedBeaconState,
proposer_index: ValidatorIndex,
@ -413,52 +370,8 @@ template partialBeaconBlock(
voluntary_exits: exits.voluntary_exits,
sync_aggregate: sync_aggregate))
proc makeBeaconBlock*(
cfg: RuntimeConfig,
state: var altair.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[altair.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[altair.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
# Signatures are verified elsewhere, so don't duplicate inefficiently here
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
# https://github.com/ethereum/consensus-specs/blob/v1.1.3/specs/merge/validator.md#block-proposal
template partialBeaconBlock(
template partialBeaconBlock*(
cfg: RuntimeConfig,
state: var bellatrix.HashedBeaconState,
proposer_index: ValidatorIndex,
@ -486,51 +399,8 @@ template partialBeaconBlock(
sync_aggregate: sync_aggregate,
execution_payload: execution_payload))
proc makeBeaconBlock*(
cfg: RuntimeConfig,
state: var bellatrix.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[bellatrix.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[bellatrix.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
# https://github.com/ethereum/consensus-specs/blob/v1.1.3/specs/merge/validator.md#block-proposal
template partialBeaconBlock(
template partialBeaconBlock*(
cfg: RuntimeConfig,
state: var capella.HashedBeaconState,
proposer_index: ValidatorIndex,
@ -563,50 +433,6 @@ template partialBeaconBlock(
bls_to_execution_changes: bls_to_execution_changes
))
proc makeBeaconBlock*(
cfg: RuntimeConfig,
state: var capella.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: capella.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[capella.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[capella.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload,
bls_to_execution_changes)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
proc makeBeaconBlock*(
cfg: RuntimeConfig,
state: var ForkedHashedBeaconState,

View File

@ -437,7 +437,8 @@ proc process_justification_and_finalization*(
balances.current_epoch_TIMELY_TARGET, flags)
proc compute_unrealized_finality*(
state: altair.BeaconState | bellatrix.BeaconState): FinalityCheckpoints =
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState):
FinalityCheckpoints =
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
return FinalityCheckpoints(
justified: state.current_justified_checkpoint,

View File

@ -207,6 +207,9 @@ func getSlotRange(dag: ChainDAGRef, startSlot: int64, count: uint64): (Slot, Slo
else: start + count
(start, ends)
from ../beacon_chain/spec/datatypes/capella import
HashedBeaconState, TrustedSignedBeaconBlock
proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
var timers: array[Timers, RunningStat]
@ -234,7 +237,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
blocks: (
seq[phase0.TrustedSignedBeaconBlock],
seq[altair.TrustedSignedBeaconBlock],
seq[bellatrix.TrustedSignedBeaconBlock])
seq[bellatrix.TrustedSignedBeaconBlock],
seq[capella.TrustedSignedBeaconBlock])
echo &"Loaded head slot {dag.head.slot}, selected {blockRefs.len} blocks"
doAssert blockRefs.len() > 0, "Must select at least one block"
@ -253,7 +257,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
blocks[2].add dag.db.getBlock(
blck.root, bellatrix.TrustedSignedBeaconBlock).get()
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
blocks[3].add dag.db.getBlock(
blck.root, capella.TrustedSignedBeaconBlock).get()
let stateData = newClone(dag.headState)
@ -263,7 +268,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
loadedState = (
(ref phase0.HashedBeaconState)(),
(ref altair.HashedBeaconState)(),
(ref bellatrix.HashedBeaconState)())
(ref bellatrix.HashedBeaconState)(),
(ref capella.HashedBeaconState)())
withTimer(timers[tLoadState]):
doAssert dag.updateState(
@ -319,19 +325,21 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
doAssert dbBenchmark.getState(
forkyState.root, loadedState[2][].data, noRollback)
of BeaconStateFork.Capella:
raiseAssert $capellaImplementationMissing
doAssert dbBenchmark.getState(
forkyState.root, loadedState[3][].data, noRollback)
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
of BeaconStateFork.Capella: hash_tree_root(loadedState[3][].data)
doAssert hash_tree_root(forkyState.data) == loadedRoot
processBlocks(blocks[0])
processBlocks(blocks[1])
processBlocks(blocks[2])
processBlocks(blocks[3])
printTimers(false, timers)
@ -343,6 +351,7 @@ proc cmdDumpState(conf: DbConf) =
phase0State = (ref phase0.HashedBeaconState)()
altairState = (ref altair.HashedBeaconState)()
bellatrixState = (ref bellatrix.HashedBeaconState)()
capellaState = (ref capella.HashedBeaconState)()
for stateRoot in conf.stateRoot:
if shouldShutDown: quit QuitSuccess
@ -359,6 +368,7 @@ proc cmdDumpState(conf: DbConf) =
doit(phase0State[])
doit(altairState[])
doit(bellatrixState[])
doit(capellaState[])
echo "Couldn't load ", stateRoot
@ -389,6 +399,8 @@ proc cmdDumpBlock(conf: DbConf) =
dump("./", blck.get())
elif (let blck = db.getBlock(root, bellatrix.TrustedSignedBeaconBlock); blck.isSome):
dump("./", blck.get())
elif (let blck = db.getBlock(root, capella.TrustedSignedBeaconBlock); blck.isSome):
dump("./", blck.get())
else:
echo "Couldn't load ", blockRoot
except CatchableError as e:

View File

@ -58,6 +58,187 @@ func gauss(r: var Rand; mu = 0.0; sigma = 1.0): float =
if b * b <= -4.0 * a * a * ln(a): break
mu + sigma * (b / a)
from ../beacon_chain/spec/state_transition_block import process_block
# TODO The rest of nimbus-eth2 uses only the forked version of these, and in
# general it's better for the validator_duties caller to use the forkedstate
# version, so isolate these here pending refactoring of block_sim to prefer,
# when possible, to also use the forked version. It'll be worth keeping some
# example of the non-forked version because it enables fork bootstrapping.
proc makeBeaconBlock(
cfg: RuntimeConfig,
state: var phase0.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[phase0.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[phase0.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
proc makeBeaconBlock(
cfg: RuntimeConfig,
state: var altair.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[altair.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[altair.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
# Signatures are verified elsewhere, so don't duplicate inefficiently here
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
proc makeBeaconBlock(
cfg: RuntimeConfig,
state: var bellatrix.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: bellatrix.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[bellatrix.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[bellatrix.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
proc makeBeaconBlock(
cfg: RuntimeConfig,
state: var capella.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockExits,
sync_aggregate: SyncAggregate,
execution_payload: capella.ExecutionPayload,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[capella.HashedBeaconState],
cache: var StateCache,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
verificationFlags: UpdateFlags = {}): Result[capella.BeaconBlock, cstring] =
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
var blck = partialBeaconBlock(
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
attestations, deposits, exits, sync_aggregate, execution_payload,
bls_to_execution_changes)
let res = process_block(
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
if res.isErr:
rollback(state)
return err(res.error())
state.root = hash_tree_root(state.data)
blck.state_root = state.root
ok(blck)
# TODO confutils is an impenetrable black box. how can a help text be added here?
cli do(slots = SLOTS_PER_EPOCH * 6,
validators = SLOTS_PER_EPOCH * 400, # One per shard is minimum

View File

@ -39,6 +39,8 @@ proc findValidator(validators: seq[Validator], pubKey: ValidatorPubKey):
else:
Opt.some idx.ValidatorIndex
from ../beacon_chain/spec/datatypes/capella import SignedBeaconBlock
cli do(validatorsDir: string, secretsDir: string,
startState: string, network: string):
let
@ -192,7 +194,14 @@ cli do(validatorsDir: string, secretsDir: string,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of BeaconBlockFork.Capella:
raiseAssert $capellaImplementationMissing
blockRoot = hash_tree_root(message.capellaData)
let signedBlock = capella.SignedBeaconBlock(
message: message.capellaData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
notice "Block proposed", message, blockRoot
aggregates.setLen(0)