block_sim runs electra (#6181)

This commit is contained in:
tersec 2024-04-07 07:58:11 +00:00 committed by GitHub
parent 27921406e9
commit 937cc62b85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 214 additions and 62 deletions

View File

@ -370,38 +370,36 @@ proc runProposalForkchoiceUpdated*(
let safeBlockHash = beaconHead.safeExecutionBlockHash
withState(self.dag.headState):
debugRaiseAssert "foo"
when consensusFork != ConsensusFork.Electra:
template callForkchoiceUpdated(fcPayloadAttributes: auto) =
let (status, _) = await self.elManager.forkchoiceUpdated(
headBlockHash, safeBlockHash,
beaconHead.finalizedExecutionBlockHash,
payloadAttributes = some fcPayloadAttributes)
debug "Fork-choice updated for proposal", status
template callForkchoiceUpdated(fcPayloadAttributes: auto) =
let (status, _) = await self.elManager.forkchoiceUpdated(
headBlockHash, safeBlockHash,
beaconHead.finalizedExecutionBlockHash,
payloadAttributes = some fcPayloadAttributes)
debug "Fork-choice updated for proposal", status
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
when consensusFork >= ConsensusFork.Deneb:
# https://github.com/ethereum/execution-apis/blob/90a46e9137c89d58e818e62fa33a0347bba50085/src/engine/prague.md
# does not define any new forkchoiceUpdated, so reuse V3 from Dencun
callForkchoiceUpdated(PayloadAttributesV3(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient,
withdrawals:
toEngineWithdrawals get_expected_withdrawals(forkyState.data),
parentBeaconBlockRoot: beaconHead.blck.bid.root.asBlockHash))
elif consensusFork >= ConsensusFork.Capella:
callForkchoiceUpdated(PayloadAttributesV2(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient,
withdrawals:
toEngineWithdrawals get_expected_withdrawals(forkyState.data)))
else:
callForkchoiceUpdated(PayloadAttributesV1(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient))
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
when consensusFork >= ConsensusFork.Deneb:
# https://github.com/ethereum/execution-apis/blob/90a46e9137c89d58e818e62fa33a0347bba50085/src/engine/prague.md
# does not define any new forkchoiceUpdated, so reuse V3 from Dencun
callForkchoiceUpdated(PayloadAttributesV3(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient,
withdrawals:
toEngineWithdrawals get_expected_withdrawals(forkyState.data),
parentBeaconBlockRoot: beaconHead.blck.bid.root.asBlockHash))
elif consensusFork >= ConsensusFork.Capella:
callForkchoiceUpdated(PayloadAttributesV2(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient,
withdrawals:
toEngineWithdrawals get_expected_withdrawals(forkyState.data)))
else:
callForkchoiceUpdated(PayloadAttributesV1(
timestamp: Quantity timestamp,
prevRandao: FixedBytes[32] randomData,
suggestedFeeRecipient: feeRecipient))
ok()

View File

@ -716,10 +716,9 @@ proc storeBlock(
template callForkChoiceUpdated: auto =
case self.consensusManager.dag.cfg.consensusForkAtEpoch(
newHead.get.blck.bid.slot.epoch)
of ConsensusFork.Electra:
let x = 4
debugRaiseAssert "callFCU"
of ConsensusFork.Deneb:
of ConsensusFork.Deneb, ConsensusFork.Electra:
# https://github.com/ethereum/execution-apis/blob/90a46e9137c89d58e818e62fa33a0347bba50085/src/engine/prague.md
# does not define any new forkchoiceUpdated, so reuse V3 from Dencun
callExpectValidFCU(payloadAttributeType = PayloadAttributesV3)
of ConsensusFork.Capella:
callExpectValidFCU(payloadAttributeType = PayloadAttributesV2)

View File

@ -1441,6 +1441,91 @@ func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
historical_summaries: pre.historical_summaries
)
func upgrade_to_electra*(cfg: RuntimeConfig, pre: deneb.BeaconState):
ref electra.BeaconState =
debugRaiseAssert "verify upgrade_to_electra"
let
epoch = get_current_epoch(pre)
latest_execution_payload_header = electra.ExecutionPayloadHeader(
parent_hash: pre.latest_execution_payload_header.parent_hash,
fee_recipient: pre.latest_execution_payload_header.fee_recipient,
state_root: pre.latest_execution_payload_header.state_root,
receipts_root: pre.latest_execution_payload_header.receipts_root,
logs_bloom: pre.latest_execution_payload_header.logs_bloom,
prev_randao: pre.latest_execution_payload_header.prev_randao,
block_number: pre.latest_execution_payload_header.block_number,
gas_limit: pre.latest_execution_payload_header.gas_limit,
gas_used: pre.latest_execution_payload_header.gas_used,
timestamp: pre.latest_execution_payload_header.timestamp,
extra_data: pre.latest_execution_payload_header.extra_data,
base_fee_per_gas: pre.latest_execution_payload_header.base_fee_per_gas,
block_hash: pre.latest_execution_payload_header.block_hash,
transactions_root: pre.latest_execution_payload_header.transactions_root,
withdrawals_root: pre.latest_execution_payload_header.withdrawals_root,
blob_gas_used: 0, # [New in Deneb]
excess_blob_gas: 0 # [New in Deneb]
)
(ref electra.BeaconState)(
# Versioning
genesis_time: pre.genesis_time,
genesis_validators_root: pre.genesis_validators_root,
slot: pre.slot,
fork: Fork(
previous_version: pre.fork.current_version,
current_version: cfg.ELECTRA_FORK_VERSION, # [Modified in Deneb]
epoch: epoch
),
# History
latest_block_header: pre.latest_block_header,
block_roots: pre.block_roots,
state_roots: pre.state_roots,
historical_roots: pre.historical_roots,
# Eth1
eth1_data: pre.eth1_data,
eth1_data_votes: pre.eth1_data_votes,
eth1_deposit_index: pre.eth1_deposit_index,
# Registry
validators: pre.validators,
balances: pre.balances,
# Randomness
randao_mixes: pre.randao_mixes,
# Slashings
slashings: pre.slashings,
# Participation
previous_epoch_participation: pre.previous_epoch_participation,
current_epoch_participation: pre.current_epoch_participation,
# Finality
justification_bits: pre.justification_bits,
previous_justified_checkpoint: pre.previous_justified_checkpoint,
current_justified_checkpoint: pre.current_justified_checkpoint,
finalized_checkpoint: pre.finalized_checkpoint,
# Inactivity
inactivity_scores: pre.inactivity_scores,
# Sync
current_sync_committee: pre.current_sync_committee,
next_sync_committee: pre.next_sync_committee,
# Execution-layer
latest_execution_payload_header: latest_execution_payload_header, # [Modified in Deneb]
# Withdrawals
next_withdrawal_index: pre.next_withdrawal_index,
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
# Deep history valid from Capella onwards
historical_summaries: pre.historical_summaries
)
func latest_block_root(state: ForkyBeaconState, state_root: Eth2Digest):
Eth2Digest =
# The root of the last block that was successfully applied to this state -

View File

@ -3363,10 +3363,7 @@ proc writeValue*(writer: var JsonWriter[RestJson],
if value.consensusValue.isSome():
writer.writeField("consensus_block_value",
$(value.consensusValue.get()))
when consensusFork == ConsensusFork.Electra:
debugRaiseAssert "electra JsonWriter ProduceBlockV3 missing"
else:
writer.writeField("data", forkyMaybeBlindedBlck)
writer.writeField("data", forkyMaybeBlindedBlck)
writer.endRecord()
proc readValue*(reader: var JsonReader[RestJson],

View File

@ -216,12 +216,25 @@ func maybeUpgradeStateToDeneb(
denebData: deneb.HashedBeaconState(
root: hash_tree_root(newState[]), data: newState[]))[]
func maybeUpgradeStateToElectra(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState) =
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
if getStateField(state, slot).epoch == cfg.ELECTRA_FORK_EPOCH and
state.kind == ConsensusFork.Deneb:
let newState = upgrade_to_electra(cfg, state.denebData.data)
state = (ref ForkedHashedBeaconState)(
kind: ConsensusFork.Electra,
electraData: electra.HashedBeaconState(
root: hash_tree_root(newState[]), data: newState[]))[]
func maybeUpgradeState*(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState) =
cfg.maybeUpgradeStateToAltair(state)
cfg.maybeUpgradeStateToBellatrix(state)
cfg.maybeUpgradeStateToCapella(state)
cfg.maybeUpgradeStateToDeneb(state)
cfg.maybeUpgradeStateToElectra(state)
proc process_slots*(
cfg: RuntimeConfig, state: var ForkedHashedBeaconState, slot: Slot,

View File

@ -142,6 +142,49 @@ proc makeSimulationBlock(
ok(blck)
proc makeSimulationBlock(
cfg: RuntimeConfig,
state: var electra.HashedBeaconState,
proposer_index: ValidatorIndex,
randao_reveal: ValidatorSig,
eth1_data: Eth1Data,
graffiti: GraffitiBytes,
attestations: seq[Attestation],
deposits: seq[Deposit],
exits: BeaconBlockValidatorChanges,
sync_aggregate: SyncAggregate,
execution_payload: electra.ExecutionPayloadForSigning,
bls_to_execution_changes: SignedBLSToExecutionChangeList,
rollback: RollbackHashedProc[electra.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[electra.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)
# TODO confutils is an impenetrable black box. how can a help text be added here?
cli do(slots = SLOTS_PER_EPOCH * 7,
validators = SLOTS_PER_EPOCH * 500,
@ -343,6 +386,8 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
addr state.capellaData
elif T is deneb.SignedBeaconBlock:
addr state.denebData
elif T is electra.SignedBeaconBlock:
addr state.electraData
else:
static: doAssert false
message = makeSimulationBlock(
@ -359,7 +404,9 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
eth1ProposalData.deposits,
BeaconBlockValidatorChanges(),
sync_aggregate,
when T is deneb.SignedBeaconBlock:
when T is electra.SignedBeaconBlock:
default(electra.ExecutionPayloadForSigning)
elif T is deneb.SignedBeaconBlock:
default(deneb.ExecutionPayloadForSigning)
elif T is capella.SignedBeaconBlock:
default(capella.ExecutionPayloadForSigning)
@ -432,6 +479,28 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
do:
raiseAssert "withUpdatedState failed"
proc proposeElectraBlock(slot: Slot) =
if rand(r, 1.0) > blockRatio:
return
dag.withUpdatedState(tmpState[], dag.getBlockIdAtSlot(slot).expect("block")) do:
let
newBlock = getNewBlock[electra.SignedBeaconBlock](updatedState, slot, cache)
added = dag.addHeadBlock(verifier, newBlock) do (
blckRef: BlockRef, signedBlock: electra.TrustedSignedBeaconBlock,
epochRef: EpochRef, unrealized: FinalityCheckpoints):
# Callback add to fork choice if valid
attPool.addForkChoice(
epochRef, blckRef, unrealized, signedBlock.message,
blckRef.slot.start_beacon_time)
dag.updateHead(added[], quarantine[], [])
if dag.needStateCachesAndForkChoicePruning():
dag.pruneStateCachesDAG()
attPool.prune()
do:
raiseAssert "withUpdatedState failed"
var
lastEth1BlockAt = genesisTime
eth1BlockNum = 1000
@ -472,12 +541,10 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
if blockRatio > 0.0:
withTimer(timers[t]):
case dag.cfg.consensusForkAtEpoch(slot.epoch)
of ConsensusFork.Electra:
echo "no electra here"
debugRaiseAssert "no electra"
of ConsensusFork.Electra: proposeElectraBlock(slot)
of ConsensusFork.Deneb: proposeDenebBlock(slot)
of ConsensusFork.Capella: proposeCapellaBlock(slot)
of ConsensusFork.Bellatrix, ConsensusFork.Altair, ConsensusFork.Phase0:
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix:
doAssert false
if attesterRatio > 0.0:
withTimer(timers[tAttest]):

View File

@ -60,7 +60,8 @@ func getSimulationConfig*(): RuntimeConfig {.compileTime.} =
cfg.ALTAIR_FORK_EPOCH = 0.Epoch
cfg.BELLATRIX_FORK_EPOCH = 0.Epoch
cfg.CAPELLA_FORK_EPOCH = 0.Epoch
cfg.DENEB_FORK_EPOCH = 2.Epoch
cfg.DENEB_FORK_EPOCH = 1.Epoch
cfg.ELECTRA_FORK_EPOCH = 3.Epoch
cfg
proc loadGenesis*(
@ -191,4 +192,4 @@ proc printTimers*[Timers: enum](
echo "Validators: ", getStateField(state, validators).len,
", epoch length: ", SLOTS_PER_EPOCH
echo "Validators per attestation (mean): ", attesters.mean
printTimers(validate, timers)
printTimers(validate, timers)

View File

@ -303,13 +303,8 @@ proc doRunTest(
let
stores = withConsensusFork(fork):
when consensusFork != ConsensusFork.Electra:
# another withFoo when it statically knows, sure, ok, so this means another place it has to be disabled
initialLoad(
path, db, consensusFork.BeaconState, consensusFork.BeaconBlock)
else:
debugRaiseAssert "electra etc"
default(tuple[dag: ChainDAGRef, fkChoice: ref ForkChoice])
initialLoad(
path, db, consensusFork.BeaconState, consensusFork.BeaconBlock)
rng = HmacDrbgContext.new()
taskpool =
@ -402,14 +397,12 @@ template fcSuite(suiteName: static[string], testPathElem: static[string]) =
continue
let fork = forkForPathComponent(path).valueOr:
raiseAssert "Unknown test fork: " & testsPath
if true:
debugRaiseAssert "no electra in fc tests"
for kind, path in walkDir(testsPath, relative = true, checkDir = true):
let basePath = testsPath/path/"pyspec_tests"
if kind != pcDir:
continue
for kind, path in walkDir(basePath, relative = true, checkDir = true):
runTest(suiteName, basePath/path, fork)
for kind, path in walkDir(testsPath, relative = true, checkDir = true):
let basePath = testsPath/path/"pyspec_tests"
if kind != pcDir:
continue
for kind, path in walkDir(basePath, relative = true, checkDir = true):
runTest(suiteName, basePath/path, fork)
from ../../beacon_chain/conf import loadKzgTrustedSetup
discard loadKzgTrustedSetup() # Required for Deneb tests

View File

@ -34,7 +34,6 @@ suite "Light client processor" & preset():
res.BELLATRIX_FORK_EPOCH = 2.Epoch
res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch
res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch
debugRaiseAssert "presumably FAR_FUTURE_EPOCH is less than optimal"
res.ELECTRA_FORK_EPOCH = FAR_FUTURE_EPOCH
res