Skip to content

Commit

Permalink
prepare builder API, modify electra BuilderBid (#6872)
Browse files Browse the repository at this point in the history
* prepare builder API, modify electra BuilderBid

* rename to blindedBlockRes and include executionRequests

* fix copyright year

* resolved review comments

* more review changes

* revert to Opt[ExecutionRequests]

* reviews
  • Loading branch information
agnxsh authored Jan 28, 2025
1 parent 5547d2a commit 65c6d1b
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 36 deletions.
3 changes: 2 additions & 1 deletion beacon_chain/spec/mev/electra_mev.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# beacon_chain
# Copyright (c) 2024 Status Research & Development GmbH
# Copyright (c) 2025 Status Research & Development GmbH
# Licensed and distributed under either of
# * 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).
Expand All @@ -20,6 +20,7 @@ type
BuilderBid* = object
header*: electra.ExecutionPayloadHeader
blob_kzg_commitments*: KzgCommitments
execution_requests*: ExecutionRequests # [New in Electra]
value*: UInt256
pubkey*: ValidatorPubKey

Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/spec/mev/fulu_mev.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# beacon_chain
# Copyright (c) 2024 Status Research & Development GmbH
# Copyright (c) 2025 Status Research & Development GmbH
# Licensed and distributed under either of
# * 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).
Expand All @@ -22,6 +22,7 @@ type
BuilderBid* = object
header*: ExecutionPayloadHeader
blob_kzg_commitments*: KzgCommitments
execution_requests*: ExecutionRequests # [New in Electra]
value*: UInt256
pubkey*: ValidatorPubKey

Expand Down
7 changes: 4 additions & 3 deletions beacon_chain/spec/state_transition.nim
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ proc makeBeaconBlockWithRewards*(
forkyState.data.latest_execution_payload_header.transactions_root =
transactions_root.get

debugComment "verify (again) that this is what builder API needs"
when executionPayload is electra.ExecutionPayloadForSigning:
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#beaconblockbody
forkyState.data.latest_block_header.body_root = hash_tree_root(
Expand All @@ -552,7 +551,8 @@ proc makeBeaconBlockWithRewards*(
hash_tree_root(sync_aggregate),
execution_payload_root.get,
hash_tree_root(validator_changes.bls_to_execution_changes),
hash_tree_root(kzg_commitments.get)
hash_tree_root(kzg_commitments.get),
hash_tree_root(execution_requests)
])
else:
raiseAssert "Attempt to use non-Electra payload with post-Deneb state"
Expand All @@ -577,7 +577,8 @@ proc makeBeaconBlockWithRewards*(
hash_tree_root(sync_aggregate),
execution_payload_root.get,
hash_tree_root(validator_changes.bls_to_execution_changes),
hash_tree_root(kzg_commitments.get)
hash_tree_root(kzg_commitments.get),
hash_tree_root(execution_requests)
])
else:
raiseAssert "Attempt to use non-Fulu payload with post-Electra state"
Expand Down
98 changes: 67 additions & 31 deletions beacon_chain/validators/beacon_validators.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type

BuilderBid[SBBB] = object
blindedBlckPart*: SBBB
executionRequests*: ExecutionRequests
executionPayloadValue*: UInt256
consensusBlockValue*: UInt256

Expand Down Expand Up @@ -458,7 +459,7 @@ proc makeBeaconBlockForHeadAndSlot*(
execution_payload_root: Opt[Eth2Digest],
withdrawals_root: Opt[Eth2Digest],
kzg_commitments: Opt[KzgCommitments],
execution_requests: ExecutionRequests): # TODO probably need this for builder API, otherwise remove, maybe needs to be Opt
execution_requests: ExecutionRequests):
Future[ForkedBlockResult] {.async: (raises: [CancelledError]).} =
# Advance state to the slot that we're proposing for
var cache = StateCache()
Expand Down Expand Up @@ -707,11 +708,23 @@ proc getBlindedExecutionPayload[
return err "getBlindedExecutionPayload: signature verification failed"

template builderBid: untyped = blindedHeader.data.message
return ok(BuilderBid[EPH](
blindedBlckPart: EPH(
execution_payload_header: builderBid.header,
blob_kzg_commitments: builderBid.blob_kzg_commitments),
executionPayloadValue: builderBid.value))
when EPH is deneb_mev.BlindedExecutionPayloadAndBlobsBundle:
return ok(BuilderBid[EPH](
blindedBlckPart: EPH(
execution_payload_header: builderBid.header,
blob_kzg_commitments: builderBid.blob_kzg_commitments),
executionRequests: default(ExecutionRequests),
executionPayloadValue: builderBid.value))
elif EPH is electra_mev.BlindedExecutionPayloadAndBlobsBundle or
EPH is fulu_mev.BlindedExecutionPayloadAndBlobsBundle:
return ok(BuilderBid[EPH](
blindedBlckPart: EPH(
execution_payload_header: builderBid.header,
blob_kzg_commitments: builderBid.blob_kzg_commitments),
executionRequests: builderBid.execution_requests,
executionPayloadValue: builderBid.value))
else:
static: doAssert false

from ./message_router_mev import
copyFields, getFieldNames, unblindAndRouteBlockMEV
Expand Down Expand Up @@ -935,7 +948,7 @@ proc getBlindedBlockParts[
slot, validator_index, head = shortLog(head)
return err("loadExecutionBlockHash failed")

executionPayloadHeader =
blindedBlockRes =
try:
awaitWithTimeout(
getBlindedExecutionPayload[EPH](
Expand All @@ -949,12 +962,12 @@ proc getBlindedBlockParts[
BlindedBlockResult[EPH].err(
"getBlindedExecutionPayload REST error: " & exc.msg)

if executionPayloadHeader.isErr:
if blindedBlockRes.isErr:
warn "Could not obtain blinded execution payload header",
error = executionPayloadHeader.error, slot, validator_index,
error = blindedBlockRes.error, slot, validator_index,
head = shortLog(head)
# Haven't committed to the MEV block, so allow EL fallback.
return err(executionPayloadHeader.error)
return err(blindedBlockRes.error)

# When creating this block, need to ensure it uses the MEV-provided execution
# payload, both to avoid repeated calls to network services and to ensure the
Expand All @@ -968,26 +981,27 @@ proc getBlindedBlockParts[
when EPH is deneb_mev.BlindedExecutionPayloadAndBlobsBundle:
type PayloadType = deneb.ExecutionPayloadForSigning
template actualEPH: untyped =
executionPayloadHeader.get.blindedBlckPart.execution_payload_header
blindedBlockRes.get.blindedBlckPart.execution_payload_header
let
withdrawals_root = Opt.some actualEPH.withdrawals_root
kzg_commitments = Opt.some(
executionPayloadHeader.get.blindedBlckPart.blob_kzg_commitments)
blindedBlockRes.get.blindedBlckPart.blob_kzg_commitments)
execution_requests = default(ExecutionRequests)

var shimExecutionPayload: PayloadType
type DenebEPH =
deneb_mev.BlindedExecutionPayloadAndBlobsBundle.execution_payload_header
copyFields(
shimExecutionPayload.executionPayload, actualEPH, getFieldNames(DenebEPH))
elif EPH is electra_mev.BlindedExecutionPayloadAndBlobsBundle:
debugComment "verify (again, after change) this is what builder API needs"
type PayloadType = electra.ExecutionPayloadForSigning
template actualEPH: untyped =
executionPayloadHeader.get.blindedBlckPart.execution_payload_header
blindedBlockRes.get.blindedBlckPart.execution_payload_header
let
withdrawals_root = Opt.some actualEPH.withdrawals_root
kzg_commitments = Opt.some(
executionPayloadHeader.get.blindedBlckPart.blob_kzg_commitments)
blindedBlockRes.get.blindedBlckPart.blob_kzg_commitments)
execution_requests = blindedBlockRes.get.executionRequests

var shimExecutionPayload: PayloadType
type ElectraEPH =
Expand All @@ -998,11 +1012,12 @@ proc getBlindedBlockParts[
debugFuluComment "verify (again, after change) this is what builder API needs"
type PayloadType = fulu.ExecutionPayloadForSigning
template actualEPH: untyped =
executionPayloadHeader.get.blindedBlckPart.execution_payload_header
blindedBlockRes.get.blindedBlckPart.execution_payload_header
let
withdrawals_root = Opt.some actualEPH.withdrawals_root
kzg_commitments = Opt.some(
executionPayloadHeader.get.blindedBlckPart.blob_kzg_commitments)
blindedBlockRes.get.blindedBlckPart.blob_kzg_commitments)
execution_requests = blindedBlockRes.get.executionRequests

var shimExecutionPayload: PayloadType
type FuluEPH =
Expand All @@ -1020,7 +1035,7 @@ proc getBlindedBlockParts[
execution_payload_root = Opt.some hash_tree_root(actualEPH),
withdrawals_root = withdrawals_root,
kzg_commitments = kzg_commitments,
execution_requests = default(ExecutionRequests))
execution_requests = execution_requests)

if newBlock.isErr():
# Haven't committed to the MEV block, so allow EL fallback.
Expand All @@ -1029,8 +1044,8 @@ proc getBlindedBlockParts[
let forkedBlck = newBlock.get()

return ok(
(executionPayloadHeader.get.blindedBlckPart,
executionPayloadHeader.get.executionPayloadValue,
(blindedBlockRes.get.blindedBlckPart,
blindedBlockRes.get.executionPayloadValue,
forkedBlck.consensusBlockValue,
forkedBlck.blck))

Expand Down Expand Up @@ -1072,11 +1087,23 @@ proc getBuilderBid[
if unsignedBlindedBlock.isErr:
return err unsignedBlindedBlock.error()

ok(BuilderBid[SBBB](
blindedBlckPart: unsignedBlindedBlock.get,
executionPayloadValue: bidValue,
consensusBlockValue: consensusValue
))
template execution_requests: untyped =
unsignedBlindedBlock.get.message.body.execution_requests
when SBBB is deneb_mev.SignedBlindedBeaconBlock:
return ok(BuilderBid[SBBB](
blindedBlckPart: unsignedBlindedBlock.get,
executionRequests: default(ExecutionRequests),
executionPayloadValue: bidValue,
consensusBlockValue: consensusValue))
elif SBBB is electra_mev.SignedBlindedBeaconBlock or
SBBB is fulu_mev.SignedBlindedBeaconBlock:
return ok(BuilderBid[SBBB](
blindedBlckPart: unsignedBlindedBlock.get,
executionRequests: execution_requests,
executionPayloadValue: bidValue,
consensusBlockValue: consensusValue))
else:
static: doAssert false

proc proposeBlockMEV(
node: BeaconNode, payloadBuilderClient: RestClientRef,
Expand Down Expand Up @@ -1164,16 +1191,25 @@ proc makeBlindedBeaconBlockForHeadAndSlot*[BBB: ForkyBlindedBeaconBlock](
blindedBlockParts.get
withBlck(forkedBlck):
when consensusFork >= ConsensusFork.Deneb:
when ((consensusFork == ConsensusFork.Deneb and
EPH is deneb_mev.BlindedExecutionPayloadAndBlobsBundle) or
(consensusFork == ConsensusFork.Electra and
EPH is electra_mev.BlindedExecutionPayloadAndBlobsBundle) or
(consensusFork == ConsensusFork.Fulu and
EPH is fulu_mev.BlindedExecutionPayloadAndBlobsBundle)):
when (consensusFork == ConsensusFork.Deneb and
EPH is deneb_mev.BlindedExecutionPayloadAndBlobsBundle):
return ok(
BuilderBid[BBB](
blindedBlckPart:
constructPlainBlindedBlock[BBB](forkyBlck, executionPayloadHeader),
executionRequests: default(ExecutionRequests),
executionPayloadValue: bidValue,
consensusBlockValue: consensusValue))

elif (consensusFork == ConsensusFork.Electra and
EPH is electra_mev.BlindedExecutionPayloadAndBlobsBundle) or
(consensusFork == ConsensusFork.Fulu and
EPH is fulu_mev.BlindedExecutionPayloadAndBlobsBundle):
return ok(
BuilderBid[BBB](
blindedBlckPart:
constructPlainBlindedBlock[BBB](forkyBlck, executionPayloadHeader),
executionRequests: forkyBlck.body.execution_requests,
executionPayloadValue: bidValue,
consensusBlockValue: consensusValue))
else:
Expand Down

0 comments on commit 65c6d1b

Please sign in to comment.