structure for supporting capella block production (#4383)
This commit is contained in:
parent
f1584eef2f
commit
4e71e77da7
|
@ -15,6 +15,8 @@ import ".."/[beacon_chain_db, beacon_node],
|
|||
".."/spec/datatypes/[phase0, altair],
|
||||
"."/[rest_utils, state_ttl_cache]
|
||||
|
||||
from ".."/spec/datatypes/bellatrix import ExecutionPayload
|
||||
|
||||
export rest_utils
|
||||
|
||||
logScope: topics = "rest_validatorapi"
|
||||
|
@ -364,8 +366,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let proposer = node.dag.getProposer(qhead, qslot)
|
||||
if proposer.isNone():
|
||||
return RestApiResponse.jsonError(Http400, ProposerNotFoundError)
|
||||
let res = await makeBeaconBlockForHeadAndSlot(
|
||||
node, qrandao, proposer.get(), qgraffiti, qhead, qslot, qskip_randao_verification)
|
||||
let res =
|
||||
await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload](
|
||||
node, qrandao, proposer.get(), qgraffiti, qhead, qslot,
|
||||
qskip_randao_verification)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400, res.error())
|
||||
res.get()
|
||||
|
@ -453,7 +457,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
bellatrixData: res.get()))
|
||||
else:
|
||||
# Pre-Bellatrix, this endpoint will return a BeaconBlock
|
||||
let res = await makeBeaconBlockForHeadAndSlot(
|
||||
let res = await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload](
|
||||
node, qrandao, proposer.get(), qgraffiti, qhead, qslot)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400, res.error())
|
||||
|
|
|
@ -456,7 +456,7 @@ func build_empty_execution_payload*(
|
|||
proc build_empty_execution_payload*(
|
||||
state: capella.BeaconState,
|
||||
feeRecipient: Eth1Address,
|
||||
expectedWithdrawals: seq[capella.Withdrawal]): capella.ExecutionPayload =
|
||||
expectedWithdrawals = newSeq[capella.Withdrawal](0)): capella.ExecutionPayload =
|
||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
||||
## without any transactions.
|
||||
let
|
||||
|
|
|
@ -327,7 +327,9 @@ template partialBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: bellatrix.ExecutionPayload): phase0.BeaconBlock =
|
||||
execution_payload: bellatrix.ExecutionPayload,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList):
|
||||
phase0.BeaconBlock =
|
||||
phase0.BeaconBlock(
|
||||
slot: state.data.slot,
|
||||
proposer_index: proposer_index.uint64,
|
||||
|
@ -354,7 +356,9 @@ template partialBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: bellatrix.ExecutionPayload): altair.BeaconBlock =
|
||||
execution_payload: bellatrix.ExecutionPayload,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList):
|
||||
altair.BeaconBlock =
|
||||
altair.BeaconBlock(
|
||||
slot: state.data.slot,
|
||||
proposer_index: proposer_index.uint64,
|
||||
|
@ -382,7 +386,9 @@ template partialBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: bellatrix.ExecutionPayload): bellatrix.BeaconBlock =
|
||||
execution_payload: bellatrix.ExecutionPayload,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList):
|
||||
bellatrix.BeaconBlock =
|
||||
bellatrix.BeaconBlock(
|
||||
slot: state.data.slot,
|
||||
proposer_index: proposer_index.uint64,
|
||||
|
@ -433,7 +439,7 @@ template partialBeaconBlock*(
|
|||
bls_to_execution_changes: bls_to_execution_changes
|
||||
))
|
||||
|
||||
proc makeBeaconBlock*(
|
||||
proc makeBeaconBlock*[T: bellatrix.ExecutionPayload | capella.ExecutionPayload](
|
||||
cfg: RuntimeConfig,
|
||||
state: var ForkedHashedBeaconState,
|
||||
proposer_index: ValidatorIndex,
|
||||
|
@ -444,15 +450,16 @@ proc makeBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits,
|
||||
sync_aggregate: SyncAggregate,
|
||||
executionPayload: bellatrix.ExecutionPayload,
|
||||
executionPayload: T,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList,
|
||||
rollback: RollbackForkedHashedProc,
|
||||
cache: var StateCache,
|
||||
# TODO:
|
||||
# `verificationFlags` is needed only in tests and can be
|
||||
# removed if we don't use invalid signatures there
|
||||
verificationFlags: UpdateFlags = {},
|
||||
transactions_root: Opt[Eth2Digest] = Opt.none Eth2Digest,
|
||||
execution_payload_root: Opt[Eth2Digest] = Opt.none Eth2Digest):
|
||||
verificationFlags: UpdateFlags,
|
||||
transactions_root: Opt[Eth2Digest],
|
||||
execution_payload_root: Opt[Eth2Digest]):
|
||||
Result[ForkedBeaconBlock, 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
|
||||
|
@ -468,7 +475,7 @@ proc makeBeaconBlock*(
|
|||
partialBeaconBlock(
|
||||
cfg, state.`kind Data`, proposer_index, randao_reveal, eth1_data,
|
||||
graffiti, attestations, deposits, exits, sync_aggregate,
|
||||
executionPayload))
|
||||
executionPayload, bls_to_execution_changes))
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.`kind Data`.data, blck.`kind Data`.asSigVerified(),
|
||||
|
@ -505,9 +512,53 @@ proc makeBeaconBlock*(
|
|||
|
||||
ok(blck)
|
||||
|
||||
case state.kind
|
||||
of BeaconStateFork.Phase0: makeBeaconBlock(phase0)
|
||||
of BeaconStateFork.Altair: makeBeaconBlock(altair)
|
||||
of BeaconStateFork.Bellatrix: makeBeaconBlock(bellatrix)
|
||||
of BeaconStateFork.Capella:
|
||||
raiseAssert $capellaImplementationMissing
|
||||
when T is bellatrix.ExecutionPayload:
|
||||
case state.kind
|
||||
of BeaconStateFork.Phase0: makeBeaconBlock(phase0)
|
||||
of BeaconStateFork.Altair: makeBeaconBlock(altair)
|
||||
of BeaconStateFork.Bellatrix: makeBeaconBlock(bellatrix)
|
||||
of BeaconStateFork.Capella: raiseAssert "Attempt to use Bellatrix payload with Capella state"
|
||||
elif T is capella.ExecutionPayload:
|
||||
case state.kind
|
||||
of BeaconStateFork.Phase0, BeaconStateFork.Altair, BeaconStateFork.Bellatrix:
|
||||
raiseAssert "Attempt to use Capella payload with non-Capella state"
|
||||
of BeaconStateFork.Capella: makeBeaconBlock(capella)
|
||||
|
||||
# workaround for https://github.com/nim-lang/Nim/issues/20900 rather than have
|
||||
# these be default arguments
|
||||
proc makeBeaconBlock*[T](
|
||||
cfg: RuntimeConfig, state: var ForkedHashedBeaconState,
|
||||
proposer_index: ValidatorIndex, randao_reveal: ValidatorSig,
|
||||
eth1_data: Eth1Data, graffiti: GraffitiBytes,
|
||||
attestations: seq[Attestation], deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits, sync_aggregate: SyncAggregate,
|
||||
executionPayload: T,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList,
|
||||
rollback: RollbackForkedHashedProc, cache: var StateCache):
|
||||
Result[ForkedBeaconBlock, cstring] =
|
||||
makeBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, executionPayload,
|
||||
bls_to_execution_changes, rollback, cache,
|
||||
verificationFlags = {},
|
||||
transactions_root = Opt.none Eth2Digest,
|
||||
execution_payload_root = Opt.none Eth2Digest)
|
||||
|
||||
proc makeBeaconBlock*[T](
|
||||
cfg: RuntimeConfig, state: var ForkedHashedBeaconState,
|
||||
proposer_index: ValidatorIndex, randao_reveal: ValidatorSig,
|
||||
eth1_data: Eth1Data, graffiti: GraffitiBytes,
|
||||
attestations: seq[Attestation], deposits: seq[Deposit],
|
||||
exits: BeaconBlockExits, sync_aggregate: SyncAggregate,
|
||||
executionPayload: T,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList,
|
||||
rollback: RollbackForkedHashedProc,
|
||||
cache: var StateCache, verificationFlags: UpdateFlags):
|
||||
Result[ForkedBeaconBlock, cstring] =
|
||||
makeBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, executionPayload,
|
||||
bls_to_execution_changes, rollback, cache,
|
||||
verificationFlags = verificationFlags,
|
||||
transactions_root = Opt.none Eth2Digest,
|
||||
execution_payload_root = Opt.none Eth2Digest)
|
||||
|
|
|
@ -462,41 +462,48 @@ proc getExecutionPayload[T](
|
|||
msg = err.msg
|
||||
return Opt.some empty_execution_payload
|
||||
|
||||
proc makeBeaconBlockForHeadAndSlot*(
|
||||
proc makeBeaconBlockForHeadAndSlot*[EP](
|
||||
node: BeaconNode, randao_reveal: ValidatorSig,
|
||||
validator_index: ValidatorIndex, graffiti: GraffitiBytes, head: BlockRef,
|
||||
slot: Slot,
|
||||
skip_randao_verification_bool: bool = false,
|
||||
execution_payload: Opt[bellatrix.ExecutionPayload] = Opt.none(bellatrix.ExecutionPayload),
|
||||
transactions_root: Opt[Eth2Digest] = Opt.none(Eth2Digest),
|
||||
execution_payload_root: Opt[Eth2Digest] = Opt.none(Eth2Digest)):
|
||||
skip_randao_verification_bool: bool,
|
||||
execution_payload: Opt[EP],
|
||||
transactions_root: Opt[Eth2Digest],
|
||||
execution_payload_root: Opt[Eth2Digest]):
|
||||
Future[ForkedBlockResult] {.async.} =
|
||||
# Advance state to the slot that we're proposing for
|
||||
var
|
||||
cache = StateCache()
|
||||
var cache = StateCache()
|
||||
|
||||
let
|
||||
# The clearance state already typically sits at the right slot per
|
||||
# `advanceClearanceState`
|
||||
state = node.dag.getProposalState(head, slot, cache).valueOr:
|
||||
beacon_block_production_errors.inc()
|
||||
return err($error)
|
||||
|
||||
# TODO can use `valueOr:`/`return err($error)` if/when
|
||||
# https://github.com/status-im/nim-stew/issues/161 is addressed
|
||||
maybeState = node.dag.getProposalState(head, slot, cache)
|
||||
|
||||
if maybeState.isErr:
|
||||
beacon_block_production_errors.inc()
|
||||
return err($maybeState.error)
|
||||
|
||||
let
|
||||
state = maybeState.get
|
||||
payloadFut =
|
||||
if executionPayload.isSome:
|
||||
let fut = newFuture[Opt[bellatrix.ExecutionPayload]]("given-payload")
|
||||
let fut = newFuture[Opt[EP]]("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[bellatrix.ExecutionPayload]]("empty-payload")
|
||||
let fut = newFuture[Opt[EP]]("empty-payload")
|
||||
# https://github.com/nim-lang/Nim/issues/19802
|
||||
fut.complete(Opt.some(default(bellatrix.ExecutionPayload)))
|
||||
fut.complete(Opt.some(default(EP)))
|
||||
fut
|
||||
else:
|
||||
# Create execution payload while packing attestations
|
||||
getExecutionPayload[bellatrix.ExecutionPayload](
|
||||
getExecutionPayload[EP](
|
||||
node, state, slot.epoch, validator_index)
|
||||
|
||||
eth1Proposal = node.getBlockProposalEth1Data(state[])
|
||||
|
@ -534,6 +541,7 @@ proc makeBeaconBlockForHeadAndSlot*(
|
|||
exits,
|
||||
syncAggregate,
|
||||
payload,
|
||||
(static(default(SignedBLSToExecutionChangeList))),
|
||||
noRollback, # Temporary state - no need for rollback
|
||||
cache,
|
||||
# makeBeaconBlock doesn't verify BLS at all, but does have special case
|
||||
|
@ -550,6 +558,29 @@ proc makeBeaconBlockForHeadAndSlot*(
|
|||
slot, head = shortLog(head), error
|
||||
$error
|
||||
|
||||
# workaround for https://github.com/nim-lang/Nim/issues/20900 to avoid default
|
||||
# parameters
|
||||
proc makeBeaconBlockForHeadAndSlot*[EP](
|
||||
node: BeaconNode, randao_reveal: ValidatorSig,
|
||||
validator_index: ValidatorIndex, graffiti: GraffitiBytes, head: BlockRef,
|
||||
slot: Slot):
|
||||
Future[ForkedBlockResult] {.async.} =
|
||||
return await makeBeaconBlockForHeadAndSlot[EP](
|
||||
node, randao_reveal, validator_index, graffiti, head, slot,
|
||||
false, execution_payload = Opt.none(EP),
|
||||
transactions_root = Opt.none(Eth2Digest),
|
||||
execution_payload_root = Opt.none(Eth2Digest))
|
||||
|
||||
proc makeBeaconBlockForHeadAndSlot*[EP](
|
||||
node: BeaconNode, randao_reveal: ValidatorSig,
|
||||
validator_index: ValidatorIndex, graffiti: GraffitiBytes, head: BlockRef,
|
||||
slot: Slot, skip_randao_verification: bool):
|
||||
Future[ForkedBlockResult] {.async.} =
|
||||
return await makeBeaconBlockForHeadAndSlot[EP](
|
||||
node, randao_reveal, validator_index, graffiti, head, slot,
|
||||
skip_randao_verification, execution_payload = Opt.none(EP),
|
||||
transactions_root = Opt.none(Eth2Digest),
|
||||
execution_payload_root = Opt.none(Eth2Digest))
|
||||
|
||||
proc getBlindedExecutionPayload(
|
||||
node: BeaconNode, slot: Slot, executionBlockRoot: Eth2Digest,
|
||||
|
@ -695,8 +726,9 @@ proc getBlindedBlockParts(
|
|||
shimExecutionPayload, executionPayloadHeader.get,
|
||||
getFieldNames(bellatrix.ExecutionPayloadHeader))
|
||||
|
||||
let newBlock = await makeBeaconBlockForHeadAndSlot(
|
||||
let newBlock = await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload](
|
||||
node, randao, validator_index, node.graffitiBytes, head, slot,
|
||||
skip_randao_verification_bool = false,
|
||||
execution_payload = Opt.some shimExecutionPayload,
|
||||
transactions_root = Opt.some executionPayloadHeader.get.transactions_root,
|
||||
execution_payload_root =
|
||||
|
@ -844,7 +876,8 @@ proc proposeBlock(node: BeaconNode,
|
|||
beacon_block_builder_missed_without_fallback.inc()
|
||||
return newBlockMEV.get
|
||||
|
||||
let newBlock = await makeBeaconBlockForHeadAndSlot(
|
||||
discard $capellaImplementationMissing & ": use capella.ExecutionPayload here as appropriate"
|
||||
let newBlock = await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload](
|
||||
node, randao, validator_index, node.graffitiBytes, head, slot)
|
||||
|
||||
if newBlock.isErr():
|
||||
|
|
|
@ -65,6 +65,10 @@ from ../beacon_chain/spec/state_transition_block import process_block
|
|||
# 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.
|
||||
|
||||
const defaultSignedBLSToExecutionChangeList =
|
||||
default(SignedBLSToExecutionChangeList)
|
||||
|
||||
proc makeBeaconBlock(
|
||||
cfg: RuntimeConfig,
|
||||
state: var phase0.HashedBeaconState,
|
||||
|
@ -94,7 +98,8 @@ proc makeBeaconBlock(
|
|||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload,
|
||||
defaultSignedBLSToExecutionChangeList)
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
|
||||
|
@ -137,7 +142,8 @@ proc makeBeaconBlock(
|
|||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload,
|
||||
defaultSignedBLSToExecutionChangeList)
|
||||
|
||||
# Signatures are verified elsewhere, so don't duplicate inefficiently here
|
||||
let res = process_block(
|
||||
|
@ -181,7 +187,8 @@ proc makeBeaconBlock(
|
|||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload,
|
||||
defaultSignedBLSToExecutionChangeList)
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
|
||||
|
@ -462,7 +469,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||
default(capella.ExecutionPayload)
|
||||
else:
|
||||
default(bellatrix.ExecutionPayload),
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
defaultSignedBLSToExecutionChangeList,
|
||||
noRollback,
|
||||
cache)
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ cli do(validatorsDir: string, secretsDir: string,
|
|||
BeaconBlockExits(),
|
||||
syncAggregate,
|
||||
default(bellatrix.ExecutionPayload),
|
||||
(static(default(SignedBLSToExecutionChangeList))),
|
||||
noRollback,
|
||||
cache).get()
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@ import
|
|||
attestation_pool, blockchain_dag, block_quarantine, block_clearance],
|
||||
./testutil, ./testdbutil, ./testblockutil
|
||||
|
||||
from ../beacon_chain/spec/datatypes/capella import
|
||||
SignedBLSToExecutionChangeList
|
||||
|
||||
func `$`(x: BlockRef): string = shortLog(x)
|
||||
|
||||
const
|
||||
|
@ -228,6 +231,7 @@ suite "Block pool processing" & preset():
|
|||
getStateField(tmpState[], eth1_data),
|
||||
default(GraffitiBytes), @[], @[], BeaconBlockExits(),
|
||||
default(SyncAggregate), default(ExecutionPayload),
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
noRollback, cache)
|
||||
check: message.isErr
|
||||
|
||||
|
@ -240,6 +244,7 @@ suite "Block pool processing" & preset():
|
|||
getStateField(tmpState[], eth1_data),
|
||||
default(GraffitiBytes), @[], @[], BeaconBlockExits(),
|
||||
default(SyncAggregate), default(ExecutionPayload),
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
noRollback, cache, {skipRandaoVerification})
|
||||
check: message.isErr
|
||||
|
||||
|
@ -252,6 +257,7 @@ suite "Block pool processing" & preset():
|
|||
getStateField(tmpState[], eth1_data),
|
||||
default(GraffitiBytes), @[], @[], BeaconBlockExits(),
|
||||
default(SyncAggregate), default(ExecutionPayload),
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
noRollback, cache, {})
|
||||
check: message.isErr
|
||||
|
||||
|
@ -264,6 +270,7 @@ suite "Block pool processing" & preset():
|
|||
getStateField(tmpState[], eth1_data),
|
||||
default(GraffitiBytes), @[], @[], BeaconBlockExits(),
|
||||
default(SyncAggregate), default(ExecutionPayload),
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
noRollback, cache, {skipRandaoVerification})
|
||||
check: message.isOk
|
||||
|
||||
|
|
|
@ -78,8 +78,11 @@ func signBlock(
|
|||
ValidatorSig()
|
||||
ForkedSignedBeaconBlock.init(forked, root, signature)
|
||||
|
||||
from ../beacon_chain/spec/datatypes/capella import
|
||||
BeaconState, ExecutionPayload
|
||||
|
||||
func build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
||||
ExecutionPayload =
|
||||
bellatrix.ExecutionPayload =
|
||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
||||
## without any transactions from a non-merged block.
|
||||
|
||||
|
@ -90,7 +93,7 @@ func build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
|||
timestamp = compute_timestamp_at_slot(state, state.slot)
|
||||
randao_mix = get_randao_mix(state, get_current_epoch(state))
|
||||
|
||||
var payload = ExecutionPayload(
|
||||
var payload = bellatrix.ExecutionPayload(
|
||||
parent_hash: latest.block_hash,
|
||||
state_root: latest.state_root, # no changes to the state
|
||||
receipts_root: EMPTY_ROOT_HASH,
|
||||
|
@ -105,17 +108,47 @@ func build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
|||
|
||||
payload
|
||||
|
||||
proc addTestBlock*(
|
||||
proc build_empty_merge_execution_payload(state: capella.BeaconState):
|
||||
capella.ExecutionPayload =
|
||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
||||
## without any transactions from a non-merged block.
|
||||
|
||||
doAssert not is_merge_transition_complete(state)
|
||||
|
||||
let
|
||||
latest = state.latest_execution_payload_header
|
||||
timestamp = compute_timestamp_at_slot(state, state.slot)
|
||||
randao_mix = get_randao_mix(state, get_current_epoch(state))
|
||||
|
||||
var payload = capella.ExecutionPayload(
|
||||
parent_hash: latest.block_hash,
|
||||
state_root: latest.state_root, # no changes to the state
|
||||
receipts_root: EMPTY_ROOT_HASH,
|
||||
block_number: latest.block_number + 1,
|
||||
prev_randao: randao_mix,
|
||||
gas_limit: 30000000, # retain same limit
|
||||
gas_used: 0, # empty block, 0 gas
|
||||
timestamp: timestamp,
|
||||
base_fee_per_gas: EIP1559_INITIAL_BASE_FEE)
|
||||
|
||||
payload.block_hash = rlpHash emptyPayloadToBlockHeader(payload)
|
||||
|
||||
payload
|
||||
|
||||
from ../beacon_chain/spec/datatypes/capella import
|
||||
SignedBLSToExecutionChangeList
|
||||
|
||||
proc addTestBlockAux[EP: bellatrix.ExecutionPayload | capella.ExecutionPayload](
|
||||
state: var ForkedHashedBeaconState,
|
||||
cache: var StateCache,
|
||||
eth1_data = Eth1Data(),
|
||||
attestations = newSeq[Attestation](),
|
||||
deposits = newSeq[Deposit](),
|
||||
sync_aggregate = SyncAggregate.init(),
|
||||
graffiti = default(GraffitiBytes),
|
||||
flags: set[UpdateFlag] = {},
|
||||
nextSlot = true,
|
||||
cfg = defaultRuntimeConfig): ForkedSignedBeaconBlock =
|
||||
eth1_data: Eth1Data,
|
||||
attestations: seq[Attestation],
|
||||
deposits: seq[Deposit],
|
||||
sync_aggregate: SyncAggregate,
|
||||
graffiti: GraffitiBytes,
|
||||
flags: set[UpdateFlag],
|
||||
nextSlot: bool,
|
||||
cfg: RuntimeConfig): ForkedSignedBeaconBlock =
|
||||
# Create and add a block to state - state will advance by one slot!
|
||||
if nextSlot:
|
||||
var info = ForkedEpochInfo()
|
||||
|
@ -138,9 +171,10 @@ proc addTestBlock*(
|
|||
|
||||
let execution_payload =
|
||||
withState(state):
|
||||
when stateFork >= BeaconStateFork.Capella:
|
||||
raiseAssert $capellaImplementationMissing
|
||||
elif stateFork >= BeaconStateFork.Bellatrix:
|
||||
when (stateFork == BeaconStateFork.Bellatrix and
|
||||
EP is bellatrix.ExecutionPayload) or
|
||||
(stateFork == BeaconStateFork.Capella and
|
||||
EP is capella.ExecutionPayload):
|
||||
# Merge shortly after Bellatrix
|
||||
if forkyState.data.slot >
|
||||
cfg.BELLATRIX_FORK_EPOCH * SLOTS_PER_EPOCH + 10:
|
||||
|
@ -150,9 +184,9 @@ proc addTestBlock*(
|
|||
else:
|
||||
build_empty_merge_execution_payload(forkyState.data)
|
||||
else:
|
||||
default(ExecutionPayload)
|
||||
default(EP)
|
||||
else:
|
||||
default(ExecutionPayload)
|
||||
default(EP)
|
||||
|
||||
let
|
||||
message = makeBeaconBlock(
|
||||
|
@ -171,6 +205,7 @@ proc addTestBlock*(
|
|||
BeaconBlockExits(),
|
||||
sync_aggregate,
|
||||
execution_payload,
|
||||
default(SignedBLSToExecutionChangeList),
|
||||
noRollback,
|
||||
cache,
|
||||
verificationFlags = {skipBlsValidation})
|
||||
|
@ -186,6 +221,22 @@ proc addTestBlock*(
|
|||
|
||||
new_block
|
||||
|
||||
proc addTestBlock*(
|
||||
state: var ForkedHashedBeaconState, cache: var StateCache,
|
||||
eth1_data = Eth1Data(), attestations = newSeq[Attestation](),
|
||||
deposits = newSeq[Deposit](), sync_aggregate = SyncAggregate.init(),
|
||||
graffiti = default(GraffitiBytes), flags: set[UpdateFlag] = {},
|
||||
nextSlot = true, cfg = defaultRuntimeConfig): ForkedSignedBeaconBlock =
|
||||
case state.kind
|
||||
of BeaconStateFork.Phase0, BeaconStateFork.Altair, BeaconStateFork.Bellatrix:
|
||||
addTestBlockAux[bellatrix.ExecutionPayload](
|
||||
state, cache, eth1_data, attestations, deposits, sync_aggregate,
|
||||
graffiti, flags, nextSlot, cfg)
|
||||
of BeaconStateFork.Capella:
|
||||
addTestBlockAux[capella.ExecutionPayload](
|
||||
state, cache, eth1_data, attestations, deposits, sync_aggregate,
|
||||
graffiti, flags, nextSlot, cfg)
|
||||
|
||||
proc makeTestBlock*(
|
||||
state: ForkedHashedBeaconState,
|
||||
cache: var StateCache,
|
||||
|
|
Loading…
Reference in New Issue