remove capella and deneb empty execution payload fallbacks (#4613)
This commit is contained in:
parent
aee19fec6b
commit
07ccd3fa6e
|
@ -449,12 +449,10 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
## Spec helpers
|
## Spec helpers
|
||||||
```diff
|
```diff
|
||||||
+ build_empty_execution_payload - Bellatrix OK
|
+ build_empty_execution_payload - Bellatrix OK
|
||||||
+ build_empty_execution_payload - Capella OK
|
|
||||||
+ build_empty_execution_payload - EIP4844 OK
|
|
||||||
+ build_proof - BeaconState OK
|
+ build_proof - BeaconState OK
|
||||||
+ integer_squareroot OK
|
+ integer_squareroot OK
|
||||||
```
|
```
|
||||||
OK: 5/5 Fail: 0/5 Skip: 0/5
|
OK: 3/3 Fail: 0/3 Skip: 0/3
|
||||||
## Specific field types
|
## Specific field types
|
||||||
```diff
|
```diff
|
||||||
+ root update OK
|
+ root update OK
|
||||||
|
@ -621,4 +619,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
||||||
OK: 9/9 Fail: 0/9 Skip: 0/9
|
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||||
|
|
||||||
---TOTAL---
|
---TOTAL---
|
||||||
OK: 346/351 Fail: 0/351 Skip: 5/351
|
OK: 344/349 Fail: 0/349 Skip: 5/349
|
||||||
|
|
|
@ -20,9 +20,11 @@ import
|
||||||
"."/[eth2_merkleization, forks, ssz_codec]
|
"."/[eth2_merkleization, forks, ssz_codec]
|
||||||
|
|
||||||
# TODO although eth2_merkleization already exports ssz_codec, *sometimes* code
|
# TODO although eth2_merkleization already exports ssz_codec, *sometimes* code
|
||||||
# fails to compile if the export is not done here also
|
# fails to compile if the export is not done here also. Exporting rlp avoids a
|
||||||
|
# generics sandwich where rlp/writer.append() is not seen, by a caller outside
|
||||||
|
# this module via compute_execution_block_hash() called from block_processor.
|
||||||
export
|
export
|
||||||
forks, eth2_merkleization, ssz_codec
|
eth2_merkleization, forks, rlp, ssz_codec
|
||||||
|
|
||||||
type
|
type
|
||||||
ExecutionWithdrawal = eth_types.Withdrawal
|
ExecutionWithdrawal = eth_types.Withdrawal
|
||||||
|
@ -202,7 +204,7 @@ func has_flag*(flags: ParticipationFlags, flag_index: int): bool =
|
||||||
let flag = ParticipationFlags(1'u8 shl flag_index)
|
let flag = ParticipationFlags(1'u8 shl flag_index)
|
||||||
(flags and flag) == flag
|
(flags and flag) == flag
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/altair/light-client/sync-protocol.md#is_sync_committee_update
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/sync-protocol.md#is_sync_committee_update
|
||||||
template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool =
|
template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool =
|
||||||
when update is SomeForkyLightClientUpdateWithSyncCommittee:
|
when update is SomeForkyLightClientUpdateWithSyncCommittee:
|
||||||
update.next_sync_committee_branch !=
|
update.next_sync_committee_branch !=
|
||||||
|
@ -217,11 +219,11 @@ template is_finality_update*(update: SomeForkyLightClientUpdate): bool =
|
||||||
else:
|
else:
|
||||||
false
|
false
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known
|
||||||
template is_next_sync_committee_known*(store: ForkyLightClientStore): bool =
|
template is_next_sync_committee_known*(store: ForkyLightClientStore): bool =
|
||||||
store.next_sync_committee != default(typeof(store.next_sync_committee))
|
store.next_sync_committee != default(typeof(store.next_sync_committee))
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/altair/light-client/sync-protocol.md#get_safety_threshold
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/sync-protocol.md#get_safety_threshold
|
||||||
func get_safety_threshold*(store: ForkyLightClientStore): uint64 =
|
func get_safety_threshold*(store: ForkyLightClientStore): uint64 =
|
||||||
max(
|
max(
|
||||||
store.previous_max_active_participants,
|
store.previous_max_active_participants,
|
||||||
|
@ -319,13 +321,13 @@ template is_better_update*[
|
||||||
new_update: A, old_update: B): bool =
|
new_update: A, old_update: B): bool =
|
||||||
is_better_data(toMeta(new_update), toMeta(old_update))
|
is_better_data(toMeta(new_update), toMeta(old_update))
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/altair/light-client/p2p-interface.md#getlightclientbootstrap
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/p2p-interface.md#getlightclientbootstrap
|
||||||
func contextEpoch*(bootstrap: ForkyLightClientBootstrap): Epoch =
|
func contextEpoch*(bootstrap: ForkyLightClientBootstrap): Epoch =
|
||||||
bootstrap.header.beacon.slot.epoch
|
bootstrap.header.beacon.slot.epoch
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/altair/light-client/p2p-interface.md#getlightclientoptimisticupdate
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/altair/light-client/p2p-interface.md#getlightclientoptimisticupdate
|
||||||
func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch =
|
func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch =
|
||||||
update.attested_header.beacon.slot.epoch
|
update.attested_header.beacon.slot.epoch
|
||||||
|
|
||||||
|
@ -481,85 +483,3 @@ proc build_empty_execution_payload*(
|
||||||
payload.block_hash = payload.compute_execution_block_hash()
|
payload.block_hash = payload.compute_execution_block_hash()
|
||||||
|
|
||||||
payload
|
payload
|
||||||
|
|
||||||
proc build_empty_execution_payload*(
|
|
||||||
state: capella.BeaconState,
|
|
||||||
feeRecipient: Eth1Address,
|
|
||||||
expectedWithdrawals = newSeq[capella.Withdrawal](0)
|
|
||||||
): capella.ExecutionPayload =
|
|
||||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
|
||||||
## without any transactions.
|
|
||||||
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))
|
|
||||||
base_fee = calcEip1599BaseFee(GasInt.saturate latest.gas_limit,
|
|
||||||
GasInt.saturate latest.gas_used,
|
|
||||||
latest.base_fee_per_gas)
|
|
||||||
|
|
||||||
var payload = capella.ExecutionPayload(
|
|
||||||
parent_hash: latest.block_hash,
|
|
||||||
fee_recipient: bellatrix.ExecutionAddress(data: distinctBase(feeRecipient)),
|
|
||||||
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: latest.gas_limit, # retain same limit
|
|
||||||
gas_used: 0, # empty block, 0 gas
|
|
||||||
timestamp: timestamp,
|
|
||||||
base_fee_per_gas: base_fee)
|
|
||||||
for withdrawal in expectedWithdrawals:
|
|
||||||
doAssert payload.withdrawals.add withdrawal
|
|
||||||
|
|
||||||
payload.block_hash = payload.compute_execution_block_hash()
|
|
||||||
|
|
||||||
payload
|
|
||||||
|
|
||||||
# https://eips.ethereum.org/EIPS/eip-4844#parameters
|
|
||||||
const
|
|
||||||
TARGET_DATA_GAS_PER_BLOCK* = 1.u256 shl 18
|
|
||||||
DATA_GAS_PER_BLOB* = 1.u256 shl 17
|
|
||||||
|
|
||||||
# https://eips.ethereum.org/EIPS/eip-4844#header-extension
|
|
||||||
func calc_excess_data_gas*(
|
|
||||||
parent: eip4844.ExecutionPayloadHeader, new_blobs: uint): UInt256 =
|
|
||||||
let consumed_data_gas = new_blobs.u256 * DATA_GAS_PER_BLOB
|
|
||||||
return
|
|
||||||
if parent.excess_data_gas + consumed_data_gas < TARGET_DATA_GAS_PER_BLOCK:
|
|
||||||
0.u256
|
|
||||||
else:
|
|
||||||
parent.excess_data_gas + consumed_data_gas - TARGET_DATA_GAS_PER_BLOCK
|
|
||||||
|
|
||||||
proc build_empty_execution_payload*(
|
|
||||||
state: eip4844.BeaconState,
|
|
||||||
feeRecipient: Eth1Address,
|
|
||||||
expectedWithdrawals = newSeq[capella.Withdrawal](0)
|
|
||||||
): eip4844.ExecutionPayload =
|
|
||||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
|
||||||
## without any transactions.
|
|
||||||
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))
|
|
||||||
base_fee = calcEip1599BaseFee(GasInt.saturate latest.gas_limit,
|
|
||||||
GasInt.saturate latest.gas_used,
|
|
||||||
latest.base_fee_per_gas)
|
|
||||||
|
|
||||||
var payload = eip4844.ExecutionPayload(
|
|
||||||
parent_hash: latest.block_hash,
|
|
||||||
fee_recipient: bellatrix.ExecutionAddress(data: distinctBase(feeRecipient)),
|
|
||||||
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: latest.gas_limit, # retain same limit
|
|
||||||
gas_used: 0, # empty block, 0 gas
|
|
||||||
timestamp: timestamp,
|
|
||||||
base_fee_per_gas: base_fee,
|
|
||||||
excess_data_gas: latest.calc_excess_data_gas(new_blobs = 0))
|
|
||||||
for withdrawal in expectedWithdrawals:
|
|
||||||
doAssert payload.withdrawals.add withdrawal
|
|
||||||
|
|
||||||
payload.block_hash = payload.compute_execution_block_hash()
|
|
||||||
|
|
||||||
payload
|
|
||||||
|
|
|
@ -300,19 +300,19 @@ proc forkchoice_updated(
|
||||||
|
|
||||||
proc get_execution_payload[EP](
|
proc get_execution_payload[EP](
|
||||||
payload_id: Option[bellatrix.PayloadID], execution_engine: Eth1Monitor):
|
payload_id: Option[bellatrix.PayloadID], execution_engine: Eth1Monitor):
|
||||||
Future[EP] {.async.} =
|
Future[Opt[EP]] {.async.} =
|
||||||
return if payload_id.isNone():
|
return if payload_id.isNone():
|
||||||
# Pre-merge, empty payload
|
# Pre-merge, empty payload
|
||||||
default(EP)
|
Opt.some default(EP)
|
||||||
else:
|
else:
|
||||||
when EP is bellatrix.ExecutionPayload:
|
when EP is bellatrix.ExecutionPayload:
|
||||||
asConsensusExecutionPayload(
|
Opt.some asConsensusExecutionPayload(
|
||||||
await execution_engine.getPayloadV1(payload_id.get))
|
await execution_engine.getPayloadV1(payload_id.get))
|
||||||
elif EP is capella.ExecutionPayload:
|
elif EP is capella.ExecutionPayload:
|
||||||
asConsensusExecutionPayload(
|
Opt.some asConsensusExecutionPayload(
|
||||||
await execution_engine.getPayloadV2(payload_id.get))
|
await execution_engine.getPayloadV2(payload_id.get))
|
||||||
elif EP is eip4844.ExecutionPayload:
|
elif EP is eip4844.ExecutionPayload:
|
||||||
asConsensusExecutionPayload(
|
Opt.some asConsensusExecutionPayload(
|
||||||
await execution_engine.getPayloadV3(payload_id.get))
|
await execution_engine.getPayloadV3(payload_id.get))
|
||||||
else:
|
else:
|
||||||
static: doAssert "unknown execution payload type"
|
static: doAssert "unknown execution payload type"
|
||||||
|
@ -345,22 +345,25 @@ proc getExecutionPayload[T](
|
||||||
# transmit this information through the Forked types, so this has to
|
# transmit this information through the Forked types, so this has to
|
||||||
# be re-proven here.
|
# be re-proven here.
|
||||||
withState(proposalState[]):
|
withState(proposalState[]):
|
||||||
when (stateFork == ConsensusFork.EIP4844 and
|
when stateFork >= ConsensusFork.Capella:
|
||||||
T is eip4844.ExecutionPayload) or
|
# As of Capella, because EL state root changes in way more difficult to
|
||||||
(stateFork == ConsensusFork.Capella and
|
# compute way from CL due to incorporation of withdrawals into EL state
|
||||||
T is capella.ExecutionPayload) or
|
# cannot use fake-EL fallback. Unlike transactions, withdrawals are not
|
||||||
(stateFork == ConsensusFork.Bellatrix and
|
# optional, so one cannot avoid this by not including any withdrawals.
|
||||||
|
Opt.none T
|
||||||
|
elif (stateFork == ConsensusFork.Bellatrix and
|
||||||
T is bellatrix.ExecutionPayload):
|
T is bellatrix.ExecutionPayload):
|
||||||
build_empty_execution_payload(forkyState.data, feeRecipient)
|
Opt.some build_empty_execution_payload(forkyState.data, feeRecipient)
|
||||||
elif stateFork >= ConsensusFork.Bellatrix:
|
elif stateFork == ConsensusFork.Bellatrix:
|
||||||
raiseAssert "getExecutionPayload: mismatched proposalState and ExecutionPayload fork"
|
raiseAssert "getExecutionPayload: mismatched proposalState and ExecutionPayload fork"
|
||||||
else:
|
else:
|
||||||
default(T)
|
# Vacuously -- these are pre-Bellatrix and not used.
|
||||||
|
Opt.some default(T)
|
||||||
|
|
||||||
if node.eth1Monitor.isNil:
|
if node.eth1Monitor.isNil:
|
||||||
beacon_block_payload_errors.inc()
|
beacon_block_payload_errors.inc()
|
||||||
warn "getExecutionPayload: eth1Monitor not initialized; using empty execution payload"
|
warn "getExecutionPayload: eth1Monitor not initialized; using empty execution payload"
|
||||||
return Opt.some empty_execution_payload
|
return empty_execution_payload
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Minimize window for Eth1 monitor to shut down connection
|
# Minimize window for Eth1 monitor to shut down connection
|
||||||
|
@ -422,12 +425,12 @@ proc getExecutionPayload[T](
|
||||||
payload_id, err = err.msg
|
payload_id, err = err.msg
|
||||||
empty_execution_payload
|
empty_execution_payload
|
||||||
|
|
||||||
return Opt.some payload
|
return payload
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
beacon_block_payload_errors.inc()
|
beacon_block_payload_errors.inc()
|
||||||
error "Error creating non-empty execution payload; using empty execution payload",
|
error "Error creating non-empty execution payload; using empty execution payload",
|
||||||
msg = err.msg
|
msg = err.msg
|
||||||
return Opt.some empty_execution_payload
|
return empty_execution_payload
|
||||||
|
|
||||||
proc getBlobsBundle(
|
proc getBlobsBundle(
|
||||||
node: BeaconNode, epoch: Epoch, validator_index: ValidatorIndex,
|
node: BeaconNode, epoch: Epoch, validator_index: ValidatorIndex,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# beacon_chain
|
# beacon_chain
|
||||||
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
@ -76,79 +76,3 @@ suite "Spec helpers":
|
||||||
|
|
||||||
testCase default(Eth1Address)
|
testCase default(Eth1Address)
|
||||||
testCase Eth1Address.fromHex("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
testCase Eth1Address.fromHex("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
||||||
|
|
||||||
test "build_empty_execution_payload - Capella":
|
|
||||||
var cfg = defaultRuntimeConfig
|
|
||||||
cfg.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
cfg.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
cfg.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
|
|
||||||
let
|
|
||||||
state = newClone(initGenesisState(cfg = cfg).capellaData)
|
|
||||||
recipient = Eth1Address.fromHex(
|
|
||||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
|
||||||
|
|
||||||
proc testCase(withdrawals: seq[capella.Withdrawal]) =
|
|
||||||
let payload = build_empty_execution_payload(
|
|
||||||
state[].data, recipient, withdrawals)
|
|
||||||
check payload.fee_recipient ==
|
|
||||||
bellatrix.ExecutionAddress(data: distinctBase(recipient))
|
|
||||||
for i, withdrawal in withdrawals:
|
|
||||||
check payload.withdrawals[i] == withdrawal
|
|
||||||
|
|
||||||
let elHeader = payloadToBlockHeader(payload)
|
|
||||||
check elHeader.withdrawalsRoot.isSome
|
|
||||||
if withdrawals.len == 0:
|
|
||||||
check elHeader.withdrawalsRoot.get == EMPTY_ROOT_HASH
|
|
||||||
else:
|
|
||||||
check elHeader.withdrawalsRoot.get != EMPTY_ROOT_HASH
|
|
||||||
check elHeader.blockHash == payload.block_hash
|
|
||||||
|
|
||||||
var bellatrixHeader = elHeader
|
|
||||||
bellatrixHeader.withdrawalsRoot.reset()
|
|
||||||
check elHeader.blockHash != rlpHash bellatrixHeader
|
|
||||||
|
|
||||||
testCase @[]
|
|
||||||
testCase @[
|
|
||||||
capella.Withdrawal(
|
|
||||||
index: 42,
|
|
||||||
validatorIndex: 1337,
|
|
||||||
address: bellatrix.ExecutionAddress(data: distinctBase(recipient)),
|
|
||||||
amount: 25.Gwei)]
|
|
||||||
testCase @[
|
|
||||||
capella.Withdrawal(
|
|
||||||
index: 1,
|
|
||||||
validatorIndex: 1,
|
|
||||||
address: bellatrix.ExecutionAddress(data: distinctBase(recipient)),
|
|
||||||
amount: 1.Gwei),
|
|
||||||
capella.Withdrawal(
|
|
||||||
index: 2,
|
|
||||||
validatorIndex: 2,
|
|
||||||
address: bellatrix.ExecutionAddress(data: distinctBase(recipient)),
|
|
||||||
amount: 2.Gwei)]
|
|
||||||
|
|
||||||
test "build_empty_execution_payload - EIP4844":
|
|
||||||
var cfg = defaultRuntimeConfig
|
|
||||||
cfg.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
cfg.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
cfg.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
cfg.EIP4844_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
|
|
||||||
let
|
|
||||||
state = newClone(initGenesisState(cfg = cfg).eip4844Data)
|
|
||||||
recipient = Eth1Address.fromHex(
|
|
||||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
|
||||||
withdrawals = @[
|
|
||||||
capella.Withdrawal(
|
|
||||||
index: 42,
|
|
||||||
validatorIndex: 1337,
|
|
||||||
address: bellatrix.ExecutionAddress(data: distinctBase(recipient)),
|
|
||||||
amount: 25.Gwei)]
|
|
||||||
|
|
||||||
payload = build_empty_execution_payload(
|
|
||||||
state[].data, recipient, withdrawals)
|
|
||||||
check:
|
|
||||||
payload.fee_recipient ==
|
|
||||||
bellatrix.ExecutionAddress(data: distinctBase(recipient))
|
|
||||||
payload.withdrawals[0] == withdrawals[0]
|
|
||||||
payload.excess_data_gas == 0.u256
|
|
||||||
|
|
|
@ -78,9 +78,6 @@ func signBlock(
|
||||||
ValidatorSig()
|
ValidatorSig()
|
||||||
ForkedSignedBeaconBlock.init(forked, root, signature)
|
ForkedSignedBeaconBlock.init(forked, root, signature)
|
||||||
|
|
||||||
from ../beacon_chain/spec/datatypes/capella import
|
|
||||||
BeaconState, ExecutionPayload, SignedBLSToExecutionChangeList
|
|
||||||
|
|
||||||
proc build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
proc build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
||||||
bellatrix.ExecutionPayload =
|
bellatrix.ExecutionPayload =
|
||||||
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
## Assuming a pre-state of the same slot, build a valid ExecutionPayload
|
||||||
|
@ -108,44 +105,17 @@ proc build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
||||||
|
|
||||||
payload
|
payload
|
||||||
|
|
||||||
proc build_empty_merge_execution_payload(state: capella.BeaconState):
|
proc addTestBlock*(
|
||||||
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 payloadToBlockHeader(payload)
|
|
||||||
|
|
||||||
payload
|
|
||||||
|
|
||||||
proc addTestBlockAux[EP: bellatrix.ExecutionPayload | capella.ExecutionPayload](
|
|
||||||
state: var ForkedHashedBeaconState,
|
state: var ForkedHashedBeaconState,
|
||||||
cache: var StateCache,
|
cache: var StateCache,
|
||||||
eth1_data: Eth1Data,
|
eth1_data: Eth1Data = Eth1Data(),
|
||||||
attestations: seq[Attestation],
|
attestations: seq[Attestation] = newSeq[Attestation](),
|
||||||
deposits: seq[Deposit],
|
deposits: seq[Deposit] = newSeq[Deposit](),
|
||||||
sync_aggregate: SyncAggregate,
|
sync_aggregate: SyncAggregate = SyncAggregate.init(),
|
||||||
graffiti: GraffitiBytes,
|
graffiti: GraffitiBytes = default(GraffitiBytes),
|
||||||
flags: set[UpdateFlag],
|
flags: set[UpdateFlag] = {},
|
||||||
nextSlot: bool,
|
nextSlot: bool = true,
|
||||||
cfg: RuntimeConfig): ForkedSignedBeaconBlock =
|
cfg: RuntimeConfig = defaultRuntimeConfig): ForkedSignedBeaconBlock =
|
||||||
# Create and add a block to state - state will advance by one slot!
|
# Create and add a block to state - state will advance by one slot!
|
||||||
if nextSlot:
|
if nextSlot:
|
||||||
var info = ForkedEpochInfo()
|
var info = ForkedEpochInfo()
|
||||||
|
@ -167,23 +137,25 @@ proc addTestBlockAux[EP: bellatrix.ExecutionPayload | capella.ExecutionPayload](
|
||||||
ValidatorSig()
|
ValidatorSig()
|
||||||
|
|
||||||
let execution_payload =
|
let execution_payload =
|
||||||
withState(state):
|
if cfg.CAPELLA_FORK_EPOCH != FAR_FUTURE_EPOCH:
|
||||||
when (stateFork == ConsensusFork.Bellatrix and
|
# Can't keep correctly doing this once Capella happens, but LVH search
|
||||||
EP is bellatrix.ExecutionPayload) or
|
# test relies on merging. So, merge only if no Capella transition.
|
||||||
(stateFork == ConsensusFork.Capella and
|
default(bellatrix.ExecutionPayload)
|
||||||
EP is capella.ExecutionPayload):
|
else:
|
||||||
# Merge shortly after Bellatrix
|
withState(state):
|
||||||
if forkyState.data.slot >
|
when stateFork == ConsensusFork.Bellatrix:
|
||||||
cfg.BELLATRIX_FORK_EPOCH * SLOTS_PER_EPOCH + 10:
|
# Merge shortly after Bellatrix
|
||||||
if is_merge_transition_complete(forkyState.data):
|
if forkyState.data.slot >
|
||||||
const feeRecipient = default(Eth1Address)
|
cfg.BELLATRIX_FORK_EPOCH * SLOTS_PER_EPOCH + 10:
|
||||||
build_empty_execution_payload(forkyState.data, feeRecipient)
|
if is_merge_transition_complete(forkyState.data):
|
||||||
|
const feeRecipient = default(Eth1Address)
|
||||||
|
build_empty_execution_payload(forkyState.data, feeRecipient)
|
||||||
|
else:
|
||||||
|
build_empty_merge_execution_payload(forkyState.data)
|
||||||
else:
|
else:
|
||||||
build_empty_merge_execution_payload(forkyState.data)
|
default(bellatrix.ExecutionPayload)
|
||||||
else:
|
else:
|
||||||
default(EP)
|
default(bellatrix.ExecutionPayload)
|
||||||
else:
|
|
||||||
default(EP)
|
|
||||||
|
|
||||||
let
|
let
|
||||||
message = makeBeaconBlock(
|
message = makeBeaconBlock(
|
||||||
|
@ -218,24 +190,6 @@ proc addTestBlockAux[EP: bellatrix.ExecutionPayload | capella.ExecutionPayload](
|
||||||
|
|
||||||
new_block
|
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 ConsensusFork.Phase0, ConsensusFork.Altair, ConsensusFork.Bellatrix:
|
|
||||||
addTestBlockAux[bellatrix.ExecutionPayload](
|
|
||||||
state, cache, eth1_data, attestations, deposits, sync_aggregate,
|
|
||||||
graffiti, flags, nextSlot, cfg)
|
|
||||||
of ConsensusFork.Capella:
|
|
||||||
addTestBlockAux[capella.ExecutionPayload](
|
|
||||||
state, cache, eth1_data, attestations, deposits, sync_aggregate,
|
|
||||||
graffiti, flags, nextSlot, cfg)
|
|
||||||
of ConsensusFork.EIP4844:
|
|
||||||
raiseAssert $eip4844ImplementationMissing & ": tests/testblockutil.nim addTestBlock"
|
|
||||||
|
|
||||||
proc makeTestBlock*(
|
proc makeTestBlock*(
|
||||||
state: ForkedHashedBeaconState,
|
state: ForkedHashedBeaconState,
|
||||||
cache: var StateCache,
|
cache: var StateCache,
|
||||||
|
|
Loading…
Reference in New Issue