use fcU V3 in Deneb/Cancun (#5293)
This commit is contained in:
parent
c3584a9ea7
commit
230626306a
|
@ -74,7 +74,9 @@ proc initLightClient*(
|
||||||
payloadAttributes = none attributes)
|
payloadAttributes = none attributes)
|
||||||
|
|
||||||
case node.dag.cfg.consensusForkAtEpoch(blck.message.slot.epoch)
|
case node.dag.cfg.consensusForkAtEpoch(blck.message.slot.epoch)
|
||||||
of ConsensusFork.Capella, ConsensusFork.Deneb:
|
of ConsensusFork.Deneb:
|
||||||
|
callForkchoiceUpdated(PayloadAttributesV3)
|
||||||
|
of ConsensusFork.Capella:
|
||||||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
||||||
# Consensus layer client MUST call this method instead of
|
# Consensus layer client MUST call this method instead of
|
||||||
# `engine_forkchoiceUpdatedV1` under any of the following
|
# `engine_forkchoiceUpdatedV1` under any of the following
|
||||||
|
|
|
@ -172,7 +172,9 @@ proc updateExecutionClientHead(self: ref ConsensusManager,
|
||||||
# Can't use dag.head here because it hasn't been updated yet
|
# Can't use dag.head here because it hasn't been updated yet
|
||||||
let (payloadExecutionStatus, latestValidHash) =
|
let (payloadExecutionStatus, latestValidHash) =
|
||||||
case self.dag.cfg.consensusForkAtEpoch(newHead.blck.bid.slot.epoch)
|
case self.dag.cfg.consensusForkAtEpoch(newHead.blck.bid.slot.epoch)
|
||||||
of ConsensusFork.Capella, ConsensusFork.Deneb:
|
of ConsensusFork.Deneb:
|
||||||
|
callForkchoiceUpdated(PayloadAttributesV3)
|
||||||
|
of ConsensusFork.Capella:
|
||||||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
||||||
# Consensus layer client MUST call this method instead of
|
# Consensus layer client MUST call this method instead of
|
||||||
# `engine_forkchoiceUpdatedV1` under any of the following conditions:
|
# `engine_forkchoiceUpdatedV1` under any of the following conditions:
|
||||||
|
@ -396,12 +398,21 @@ proc runProposalForkchoiceUpdated*(
|
||||||
debug "Fork-choice updated for proposal", status
|
debug "Fork-choice updated for proposal", status
|
||||||
|
|
||||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||||
when consensusFork >= ConsensusFork.Capella:
|
when consensusFork >= ConsensusFork.Deneb:
|
||||||
|
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(
|
callForkchoiceUpdated(PayloadAttributesV2(
|
||||||
timestamp: Quantity timestamp,
|
timestamp: Quantity timestamp,
|
||||||
prevRandao: FixedBytes[32] randomData,
|
prevRandao: FixedBytes[32] randomData,
|
||||||
suggestedFeeRecipient: feeRecipient,
|
suggestedFeeRecipient: feeRecipient,
|
||||||
withdrawals: toEngineWithdrawals get_expected_withdrawals(forkyState.data)))
|
withdrawals:
|
||||||
|
toEngineWithdrawals get_expected_withdrawals(forkyState.data)))
|
||||||
else:
|
else:
|
||||||
callForkchoiceUpdated(PayloadAttributesV1(
|
callForkchoiceUpdated(PayloadAttributesV1(
|
||||||
timestamp: Quantity timestamp,
|
timestamp: Quantity timestamp,
|
||||||
|
|
|
@ -140,7 +140,7 @@ type
|
||||||
headBlockHash*: Eth2Digest
|
headBlockHash*: Eth2Digest
|
||||||
safeBlockHash*: Eth2Digest
|
safeBlockHash*: Eth2Digest
|
||||||
finalizedBlockHash*: Eth2Digest
|
finalizedBlockHash*: Eth2Digest
|
||||||
payloadAttributes*: PayloadAttributesV2
|
payloadAttributes*: PayloadAttributesV3
|
||||||
|
|
||||||
ELManager* = ref object
|
ELManager* = ref object
|
||||||
eth1Network: Option[Eth1Network]
|
eth1Network: Option[Eth1Network]
|
||||||
|
@ -767,7 +767,8 @@ func areSameAs(expectedParams: Option[NextExpectedPayloadParams],
|
||||||
timestamp: uint64,
|
timestamp: uint64,
|
||||||
randomData: Eth2Digest,
|
randomData: Eth2Digest,
|
||||||
feeRecipient: Eth1Address,
|
feeRecipient: Eth1Address,
|
||||||
withdrawals: seq[WithdrawalV1]): bool =
|
withdrawals: seq[WithdrawalV1],
|
||||||
|
parentBeaconBlockRoot: FixedBytes[32]): bool =
|
||||||
expectedParams.isSome and
|
expectedParams.isSome and
|
||||||
expectedParams.get.headBlockHash == latestHead and
|
expectedParams.get.headBlockHash == latestHead and
|
||||||
expectedParams.get.safeBlockHash == latestSafe and
|
expectedParams.get.safeBlockHash == latestSafe and
|
||||||
|
@ -775,17 +776,22 @@ func areSameAs(expectedParams: Option[NextExpectedPayloadParams],
|
||||||
expectedParams.get.payloadAttributes.timestamp.uint64 == timestamp and
|
expectedParams.get.payloadAttributes.timestamp.uint64 == timestamp and
|
||||||
expectedParams.get.payloadAttributes.prevRandao.bytes == randomData.data and
|
expectedParams.get.payloadAttributes.prevRandao.bytes == randomData.data and
|
||||||
expectedParams.get.payloadAttributes.suggestedFeeRecipient == feeRecipient and
|
expectedParams.get.payloadAttributes.suggestedFeeRecipient == feeRecipient and
|
||||||
expectedParams.get.payloadAttributes.withdrawals == withdrawals
|
expectedParams.get.payloadAttributes.withdrawals == withdrawals and
|
||||||
|
expectedParams.get.payloadAttributes.parentBeaconBlockRoot ==
|
||||||
|
parentBeaconBlockRoot
|
||||||
|
|
||||||
proc forkchoiceUpdated(rpcClient: RpcClient,
|
proc forkchoiceUpdated(rpcClient: RpcClient,
|
||||||
state: ForkchoiceStateV1,
|
state: ForkchoiceStateV1,
|
||||||
payloadAttributes: Option[PayloadAttributesV1] |
|
payloadAttributes: Option[PayloadAttributesV1] |
|
||||||
Option[PayloadAttributesV2]):
|
Option[PayloadAttributesV2] |
|
||||||
|
Option[PayloadAttributesV3]):
|
||||||
Future[ForkchoiceUpdatedResponse] =
|
Future[ForkchoiceUpdatedResponse] =
|
||||||
when payloadAttributes is Option[PayloadAttributesV1]:
|
when payloadAttributes is Option[PayloadAttributesV1]:
|
||||||
rpcClient.engine_forkchoiceUpdatedV1(state, payloadAttributes)
|
rpcClient.engine_forkchoiceUpdatedV1(state, payloadAttributes)
|
||||||
elif payloadAttributes is Option[PayloadAttributesV2]:
|
elif payloadAttributes is Option[PayloadAttributesV2]:
|
||||||
rpcClient.engine_forkchoiceUpdatedV2(state, payloadAttributes)
|
rpcClient.engine_forkchoiceUpdatedV2(state, payloadAttributes)
|
||||||
|
elif payloadAttributes is Option[PayloadAttributesV3]:
|
||||||
|
rpcClient.engine_forkchoiceUpdatedV3(state, payloadAttributes)
|
||||||
else:
|
else:
|
||||||
static: doAssert false
|
static: doAssert false
|
||||||
|
|
||||||
|
@ -799,6 +805,7 @@ proc getPayloadFromSingleEL(
|
||||||
connection: ELConnection,
|
connection: ELConnection,
|
||||||
GetPayloadResponseType: type,
|
GetPayloadResponseType: type,
|
||||||
isForkChoiceUpToDate: bool,
|
isForkChoiceUpToDate: bool,
|
||||||
|
consensusHead: Eth2Digest,
|
||||||
headBlock, safeBlock, finalizedBlock: Eth2Digest,
|
headBlock, safeBlock, finalizedBlock: Eth2Digest,
|
||||||
timestamp: uint64,
|
timestamp: uint64,
|
||||||
randomData: Eth2Digest,
|
randomData: Eth2Digest,
|
||||||
|
@ -822,8 +829,7 @@ proc getPayloadFromSingleEL(
|
||||||
timestamp: Quantity timestamp,
|
timestamp: Quantity timestamp,
|
||||||
prevRandao: FixedBytes[32] randomData.data,
|
prevRandao: FixedBytes[32] randomData.data,
|
||||||
suggestedFeeRecipient: suggestedFeeRecipient))
|
suggestedFeeRecipient: suggestedFeeRecipient))
|
||||||
elif GetPayloadResponseType is engine_api.GetPayloadV2Response or
|
elif GetPayloadResponseType is engine_api.GetPayloadV2Response:
|
||||||
GetPayloadResponseType is engine_api.GetPayloadV3Response:
|
|
||||||
let response = await rpcClient.forkchoiceUpdated(
|
let response = await rpcClient.forkchoiceUpdated(
|
||||||
ForkchoiceStateV1(
|
ForkchoiceStateV1(
|
||||||
headBlockHash: headBlock.asBlockHash,
|
headBlockHash: headBlock.asBlockHash,
|
||||||
|
@ -834,6 +840,18 @@ proc getPayloadFromSingleEL(
|
||||||
prevRandao: FixedBytes[32] randomData.data,
|
prevRandao: FixedBytes[32] randomData.data,
|
||||||
suggestedFeeRecipient: suggestedFeeRecipient,
|
suggestedFeeRecipient: suggestedFeeRecipient,
|
||||||
withdrawals: withdrawals))
|
withdrawals: withdrawals))
|
||||||
|
elif GetPayloadResponseType is engine_api.GetPayloadV3Response:
|
||||||
|
let response = await rpcClient.forkchoiceUpdated(
|
||||||
|
ForkchoiceStateV1(
|
||||||
|
headBlockHash: headBlock.asBlockHash,
|
||||||
|
safeBlockHash: safeBlock.asBlockHash,
|
||||||
|
finalizedBlockHash: finalizedBlock.asBlockHash),
|
||||||
|
some PayloadAttributesV3(
|
||||||
|
timestamp: Quantity timestamp,
|
||||||
|
prevRandao: FixedBytes[32] randomData.data,
|
||||||
|
suggestedFeeRecipient: suggestedFeeRecipient,
|
||||||
|
withdrawals: withdrawals,
|
||||||
|
parentBeaconBlockRoot: consensusHead.asBlockHash))
|
||||||
else:
|
else:
|
||||||
static: doAssert false
|
static: doAssert false
|
||||||
|
|
||||||
|
@ -849,7 +867,8 @@ proc getPayloadFromSingleEL(
|
||||||
raise newException(CatchableError, "No confirmed execution head yet")
|
raise newException(CatchableError, "No confirmed execution head yet")
|
||||||
|
|
||||||
when GetPayloadResponseType is BellatrixExecutionPayloadWithValue:
|
when GetPayloadResponseType is BellatrixExecutionPayloadWithValue:
|
||||||
let payload= await engine_api.getPayload(rpcClient, ExecutionPayloadV1, payloadId)
|
let payload =
|
||||||
|
await engine_api.getPayload(rpcClient, ExecutionPayloadV1, payloadId)
|
||||||
return BellatrixExecutionPayloadWithValue(
|
return BellatrixExecutionPayloadWithValue(
|
||||||
executionPayload: payload,
|
executionPayload: payload,
|
||||||
blockValue: computeBlockValue payload)
|
blockValue: computeBlockValue payload)
|
||||||
|
@ -891,6 +910,7 @@ template toFork(T: type ExecutionPayloadV3): ConsensusFork =
|
||||||
|
|
||||||
proc getPayload*(m: ELManager,
|
proc getPayload*(m: ELManager,
|
||||||
PayloadType: type ForkyExecutionPayloadForSigning,
|
PayloadType: type ForkyExecutionPayloadForSigning,
|
||||||
|
consensusHead: Eth2Digest,
|
||||||
headBlock, safeBlock, finalizedBlock: Eth2Digest,
|
headBlock, safeBlock, finalizedBlock: Eth2Digest,
|
||||||
timestamp: uint64,
|
timestamp: uint64,
|
||||||
randomData: Eth2Digest,
|
randomData: Eth2Digest,
|
||||||
|
@ -902,9 +922,10 @@ proc getPayload*(m: ELManager,
|
||||||
|
|
||||||
let
|
let
|
||||||
engineApiWithdrawals = toEngineWithdrawals withdrawals
|
engineApiWithdrawals = toEngineWithdrawals withdrawals
|
||||||
let isFcUpToDate = m.nextExpectedPayloadParams.areSameAs(
|
isFcUpToDate = m.nextExpectedPayloadParams.areSameAs(
|
||||||
headBlock, safeBlock, finalizedBlock, timestamp,
|
headBlock, safeBlock, finalizedBlock, timestamp,
|
||||||
randomData, suggestedFeeRecipient, engineApiWithdrawals)
|
randomData, suggestedFeeRecipient, engineApiWithdrawals,
|
||||||
|
consensusHead.asBlockHash)
|
||||||
|
|
||||||
# `getPayloadFromSingleEL` may introduce additional latency
|
# `getPayloadFromSingleEL` may introduce additional latency
|
||||||
const extraProcessingOverhead = 500.milliseconds
|
const extraProcessingOverhead = 500.milliseconds
|
||||||
|
@ -913,7 +934,7 @@ proc getPayload*(m: ELManager,
|
||||||
deadline = sleepAsync(timeout)
|
deadline = sleepAsync(timeout)
|
||||||
requests = m.elConnections.mapIt(it.getPayloadFromSingleEL(
|
requests = m.elConnections.mapIt(it.getPayloadFromSingleEL(
|
||||||
EngineApiResponseType(PayloadType),
|
EngineApiResponseType(PayloadType),
|
||||||
isFcUpToDate, headBlock, safeBlock, finalizedBlock,
|
isFcUpToDate, consensusHead, headBlock, safeBlock, finalizedBlock,
|
||||||
timestamp, randomData, suggestedFeeRecipient, engineApiWithdrawals
|
timestamp, randomData, suggestedFeeRecipient, engineApiWithdrawals
|
||||||
))
|
))
|
||||||
requestsCompleted = allFutures(requests)
|
requestsCompleted = allFutures(requests)
|
||||||
|
@ -1221,7 +1242,8 @@ proc forkchoiceUpdatedForSingleEL(
|
||||||
connection: ELConnection,
|
connection: ELConnection,
|
||||||
state: ref ForkchoiceStateV1,
|
state: ref ForkchoiceStateV1,
|
||||||
payloadAttributes: Option[PayloadAttributesV1] |
|
payloadAttributes: Option[PayloadAttributesV1] |
|
||||||
Option[PayloadAttributesV2]):
|
Option[PayloadAttributesV2] |
|
||||||
|
Option[PayloadAttributesV3]):
|
||||||
Future[PayloadStatusV1] {.async.} =
|
Future[PayloadStatusV1] {.async.} =
|
||||||
let
|
let
|
||||||
rpcClient = await connection.connectedRpcClient()
|
rpcClient = await connection.connectedRpcClient()
|
||||||
|
@ -1242,7 +1264,8 @@ proc forkchoiceUpdated*(m: ELManager,
|
||||||
headBlockHash, safeBlockHash,
|
headBlockHash, safeBlockHash,
|
||||||
finalizedBlockHash: Eth2Digest,
|
finalizedBlockHash: Eth2Digest,
|
||||||
payloadAttributes: Option[PayloadAttributesV1] |
|
payloadAttributes: Option[PayloadAttributesV1] |
|
||||||
Option[PayloadAttributesV2]):
|
Option[PayloadAttributesV2] |
|
||||||
|
Option[PayloadAttributesV3]):
|
||||||
Future[(PayloadExecutionStatus, Option[BlockHash])] {.async.} =
|
Future[(PayloadExecutionStatus, Option[BlockHash])] {.async.} =
|
||||||
doAssert not headBlockHash.isZero
|
doAssert not headBlockHash.isZero
|
||||||
|
|
||||||
|
@ -1260,24 +1283,37 @@ proc forkchoiceUpdated*(m: ELManager,
|
||||||
if m.elConnections.len == 0:
|
if m.elConnections.len == 0:
|
||||||
return (PayloadExecutionStatus.syncing, none BlockHash)
|
return (PayloadExecutionStatus.syncing, none BlockHash)
|
||||||
|
|
||||||
when payloadAttributes is Option[PayloadAttributesV2]:
|
when payloadAttributes is Option[PayloadAttributesV3]:
|
||||||
template payloadAttributesV2(): auto =
|
template payloadAttributesV3(): auto =
|
||||||
if payloadAttributes.isSome:
|
if payloadAttributes.isSome:
|
||||||
payloadAttributes.get
|
payloadAttributes.get
|
||||||
else:
|
else:
|
||||||
# As timestamp and prevRandao are both 0, won't false-positive match
|
# As timestamp and prevRandao are both 0, won't false-positive match
|
||||||
(static(default(PayloadAttributesV2)))
|
(static(default(PayloadAttributesV3)))
|
||||||
elif payloadAttributes is Option[PayloadAttributesV1]:
|
elif payloadAttributes is Option[PayloadAttributesV2]:
|
||||||
template payloadAttributesV2(): auto =
|
template payloadAttributesV3(): auto =
|
||||||
if payloadAttributes.isSome:
|
if payloadAttributes.isSome:
|
||||||
PayloadAttributesV2(
|
PayloadAttributesV3(
|
||||||
timestamp: payloadAttributes.get.timestamp,
|
timestamp: payloadAttributes.get.timestamp,
|
||||||
prevRandao: payloadAttributes.get.prevRandao,
|
prevRandao: payloadAttributes.get.prevRandao,
|
||||||
suggestedFeeRecipient: payloadAttributes.get.suggestedFeeRecipient,
|
suggestedFeeRecipient: payloadAttributes.get.suggestedFeeRecipient,
|
||||||
withdrawals: @[])
|
withdrawals: payloadAttributes.get.withdrawals,
|
||||||
|
parentBeaconBlockRoot: static(default(FixedBytes[32])))
|
||||||
else:
|
else:
|
||||||
# As timestamp and prevRandao are both 0, won't false-positive match
|
# As timestamp and prevRandao are both 0, won't false-positive match
|
||||||
(static(default(PayloadAttributesV2)))
|
(static(default(PayloadAttributesV3)))
|
||||||
|
elif payloadAttributes is Option[PayloadAttributesV1]:
|
||||||
|
template payloadAttributesV3(): auto =
|
||||||
|
if payloadAttributes.isSome:
|
||||||
|
PayloadAttributesV3(
|
||||||
|
timestamp: payloadAttributes.get.timestamp,
|
||||||
|
prevRandao: payloadAttributes.get.prevRandao,
|
||||||
|
suggestedFeeRecipient: payloadAttributes.get.suggestedFeeRecipient,
|
||||||
|
withdrawals: @[],
|
||||||
|
parentBeaconBlockRoot: static(default(FixedBytes[32])))
|
||||||
|
else:
|
||||||
|
# As timestamp and prevRandao are both 0, won't false-positive match
|
||||||
|
(static(default(PayloadAttributesV3)))
|
||||||
else:
|
else:
|
||||||
static: doAssert false
|
static: doAssert false
|
||||||
|
|
||||||
|
@ -1319,7 +1355,7 @@ proc forkchoiceUpdated*(m: ELManager,
|
||||||
headBlockHash: headBlockHash,
|
headBlockHash: headBlockHash,
|
||||||
safeBlockHash: safeBlockHash,
|
safeBlockHash: safeBlockHash,
|
||||||
finalizedBlockHash: finalizedBlockHash,
|
finalizedBlockHash: finalizedBlockHash,
|
||||||
payloadAttributes: payloadAttributesV2))
|
payloadAttributes: payloadAttributesV3))
|
||||||
|
|
||||||
if responseProcessor.disagreementAlreadyDetected:
|
if responseProcessor.disagreementAlreadyDetected:
|
||||||
return (PayloadExecutionStatus.invalid, none BlockHash)
|
return (PayloadExecutionStatus.invalid, none BlockHash)
|
||||||
|
|
|
@ -233,8 +233,8 @@ proc storeBackfillBlock(
|
||||||
res
|
res
|
||||||
|
|
||||||
from web3/engine_api_types import
|
from web3/engine_api_types import
|
||||||
PayloadAttributesV1, PayloadAttributesV2, PayloadExecutionStatus,
|
PayloadAttributesV1, PayloadAttributesV2, PayloadAttributesV3,
|
||||||
PayloadStatusV1
|
PayloadExecutionStatus, PayloadStatusV1
|
||||||
from ../el/el_manager import
|
from ../el/el_manager import
|
||||||
ELManager, forkchoiceUpdated, hasConnection, hasProperlyConfiguredConnection,
|
ELManager, forkchoiceUpdated, hasConnection, hasProperlyConfiguredConnection,
|
||||||
sendNewPayload
|
sendNewPayload
|
||||||
|
@ -616,7 +616,9 @@ proc storeBlock*(
|
||||||
|
|
||||||
case self.consensusManager.dag.cfg.consensusForkAtEpoch(
|
case self.consensusManager.dag.cfg.consensusForkAtEpoch(
|
||||||
newHead.get.blck.bid.slot.epoch)
|
newHead.get.blck.bid.slot.epoch)
|
||||||
of ConsensusFork.Capella, ConsensusFork.Deneb:
|
of ConsensusFork.Deneb:
|
||||||
|
callForkchoiceUpdated(PayloadAttributesV3)
|
||||||
|
of ConsensusFork.Capella:
|
||||||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#specification-1
|
||||||
# Consensus layer client MUST call this method instead of
|
# Consensus layer client MUST call this method instead of
|
||||||
# `engine_forkchoiceUpdatedV1` under any of the following conditions:
|
# `engine_forkchoiceUpdatedV1` under any of the following conditions:
|
||||||
|
|
|
@ -311,8 +311,8 @@ proc getExecutionPayload(
|
||||||
else:
|
else:
|
||||||
@[]
|
@[]
|
||||||
payload = await node.elManager.getPayload(
|
payload = await node.elManager.getPayload(
|
||||||
PayloadType, executionHead, latestSafe, latestFinalized,
|
PayloadType, beaconHead.blck.bid.root, executionHead, latestSafe,
|
||||||
timestamp, random, feeRecipient, withdrawals)
|
latestFinalized, timestamp, random, feeRecipient, withdrawals)
|
||||||
|
|
||||||
if payload.isNone:
|
if payload.isNone:
|
||||||
error "Failed to obtain execution payload from EL",
|
error "Failed to obtain execution payload from EL",
|
||||||
|
|
Loading…
Reference in New Issue