Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update Deneb for latest builder-specs flow #5598

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 42 additions & 64 deletions beacon_chain/rpc/rest_beacon_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1006,78 +1006,56 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
(currentEpochFork.toString != version):
return RestApiResponse.jsonError(Http400, BlockIncorrectFork)

case currentEpochFork
of ConsensusFork.Deneb:
let
restBlockContents = decodeBodyJsonOrSsz(deneb_mev.SignedBlindedBeaconBlockContents,
body).valueOr:
return RestApiResponse.jsonError(error)
withConsensusFork(currentEpochFork):
when consensusFork >= ConsensusFork.Capella:
let
restBlock = decodeBodyJsonOrSsz(
consensusFork.SignedBlindedBeaconBlock, body).valueOr:
return RestApiResponse.jsonError(error)
payloadBuilderClient = node.getPayloadBuilderClient(
restBlock.message.proposer_index).valueOr:
return RestApiResponse.jsonError(
Http400, "Unable to initialize payload builder client: " & $error)
res = await node.unblindAndRouteBlockMEV(
payloadBuilderClient, restBlock)

payloadBuilderClient = node.getPayloadBuilderClient(
restBlockContents.signed_blinded_block.message.proposer_index).valueOr:
if res.isErr():
return RestApiResponse.jsonError(
Http400, "Unable to initialize payload builder client: " & $error)
res = await node.unblindAndRouteBlockMEV(
payloadBuilderClient, restBlockContents)
Http500, InternalServerError, $res.error())
if res.get().isNone():
return RestApiResponse.jsonError(Http202, BlockValidationError)

if res.isErr():
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
elif consensusFork >= ConsensusFork.Bellatrix:
return RestApiResponse.jsonError(
Http500, InternalServerError, $res.error())
if res.get().isNone():
return RestApiResponse.jsonError(Http202, BlockValidationError)

return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
of ConsensusFork.Capella:
let
restBlock =
decodeBodyJsonOrSsz(capella_mev.SignedBlindedBeaconBlock,
body).valueOr:
return RestApiResponse.jsonError(error)
Http400, $consensusFork & " builder API unsupported")
else:
# Pre-Bellatrix, this endpoint will accept a `SignedBeaconBlock`.
#
# This is mostly the same as /eth/v1/beacon/blocks for phase 0 and
# altair.
var
restBlock = decodeBody(
RestPublishedSignedBeaconBlock, body, version).valueOr:
return RestApiResponse.jsonError(error)
forked = ForkedSignedBeaconBlock(restBlock)

payloadBuilderClient = node.getPayloadBuilderClient(
restBlock.message.proposer_index).valueOr:
return RestApiResponse.jsonError(
Http400, "Unable to initialize payload builder client: " & $error)
res = await node.unblindAndRouteBlockMEV(
payloadBuilderClient, restBlock)
if forked.kind != node.dag.cfg.consensusForkAtEpoch(
getForkedBlockField(forked, slot).epoch):
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)

if res.isErr():
return RestApiResponse.jsonError(
Http500, InternalServerError, $res.error())
if res.get().isNone():
return RestApiResponse.jsonError(Http202, BlockValidationError)
let res = withBlck(forked):
forkyBlck.root = hash_tree_root(forkyBlck.message)
await node.router.routeSignedBeaconBlock(
forkyBlck, Opt.none(seq[BlobSidecar]))

return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
of ConsensusFork.Bellatrix:
return RestApiResponse.jsonError(Http400,
"Bellatrix builder API unsupported")
of ConsensusFork.Altair, ConsensusFork.Phase0:
# Pre-Bellatrix, this endpoint will accept a `SignedBeaconBlock`.
#
# This is mostly the same as /eth/v1/beacon/blocks for phase 0 and
# altair.
var
restBlock = decodeBody(RestPublishedSignedBeaconBlock, body,
version).valueOr:
return RestApiResponse.jsonError(error)
forked = ForkedSignedBeaconBlock(restBlock)

if forked.kind != node.dag.cfg.consensusForkAtEpoch(
getForkedBlockField(forked, slot).epoch):
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)

let res = withBlck(forked):
forkyBlck.root = hash_tree_root(forkyBlck.message)
await node.router.routeSignedBeaconBlock(
forkyBlck, Opt.none(seq[BlobSidecar]))

if res.isErr():
return RestApiResponse.jsonError(
Http503, BeaconNodeInSyncError, $res.error())
elif res.get().isNone():
return RestApiResponse.jsonError(Http202, BlockValidationError)
if res.isErr():
return RestApiResponse.jsonError(
Http503, BeaconNodeInSyncError, $res.error())
elif res.get().isNone():
return RestApiResponse.jsonError(Http202, BlockValidationError)

return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)

# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlock
router.api(MethodGet, "/eth/v1/beacon/blocks/{block_id}") do (
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ type
SetGasLimitRequest |
bellatrix_mev.SignedBlindedBeaconBlock |
capella_mev.SignedBlindedBeaconBlock |
deneb_mev.SignedBlindedBeaconBlockContents |
deneb_mev.SignedBlindedBeaconBlock |
SignedValidatorRegistrationV1 |
SignedVoluntaryExit |
Web3SignerRequest |
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/spec/eth2_apis/rest_beacon_calls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ proc publishBlindedBlock*(body: capella_mev.SignedBlindedBeaconBlock):
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock

proc publishBlindedBlock*(body: deneb_mev.SignedBlindedBeaconBlockContents):
proc publishBlindedBlock*(body: deneb_mev.SignedBlindedBeaconBlock):
RestPlainResponse {.
rest, endpoint: "/eth/v1/beacon/blinded_blocks",
meth: MethodPost.}
Expand Down
16 changes: 14 additions & 2 deletions beacon_chain/spec/forks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ template kind*(
capella.TrustedBeaconBlockBody |
capella.SigVerifiedSignedBeaconBlock |
capella.MsgTrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock]): ConsensusFork =
capella.TrustedSignedBeaconBlock |
capella_mev.SignedBlindedBeaconBlock]): ConsensusFork =
ConsensusFork.Capella

template kind*(
Expand All @@ -335,7 +336,8 @@ template kind*(
deneb.TrustedBeaconBlockBody |
deneb.SigVerifiedSignedBeaconBlock |
deneb.MsgTrustedSignedBeaconBlock |
deneb.TrustedSignedBeaconBlock]): ConsensusFork =
deneb.TrustedSignedBeaconBlock |
deneb_mev.SignedBlindedBeaconBlock]): ConsensusFork =
ConsensusFork.Deneb

template BeaconState*(kind: static ConsensusFork): auto =
Expand Down Expand Up @@ -418,6 +420,16 @@ template ExecutionPayloadForSigning*(kind: static ConsensusFork): auto =
else:
static: raiseAssert "Unreachable"

template SignedBlindedBeaconBlock*(kind: static ConsensusFork): auto =
when kind == ConsensusFork.Deneb:
typedesc[deneb_mev.SignedBlindedBeaconBlock]
elif kind == ConsensusFork.Capella:
typedesc[capella_mev.SignedBlindedBeaconBlock]
elif kind == ConsensusFork.Bellatrix:
static: raiseAssert "Unsupported"
else:
static: raiseAssert "Unreachable"

template withAll*(
x: typedesc[ConsensusFork], body: untyped): untyped =
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
Expand Down
24 changes: 0 additions & 24 deletions beacon_chain/spec/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -235,30 +235,6 @@ func create_blob_sidecars*(
res.add(sidecar)
res

func create_blob_sidecars*(
forkyBlck: deneb_mev.SignedBlindedBeaconBlock,
kzg_proofs: KzgProofs,
blob_roots: BlobRoots): seq[BlindedBlobSidecar] =
template kzg_commitments: untyped =
forkyBlck.message.body.blob_kzg_commitments
doAssert kzg_proofs.len == blob_roots.len
doAssert kzg_proofs.len == kzg_commitments.len

var res = newSeqOfCap[BlindedBlobSidecar](blob_roots.len)
let signedBlockHeader = forkyBlck.toSignedBeaconBlockHeader()
for i in 0 ..< blob_roots.lenu64:
var sidecar = BlindedBlobSidecar(
index: i,
blob_root: blob_roots[i],
kzg_commitment: kzg_commitments[i],
kzg_proof: kzg_proofs[i],
signed_block_header: signedBlockHeader)
forkyBlck.message.body.build_proof(
kzg_commitment_inclusion_proof_gindex(i),
sidecar.kzg_commitment_inclusion_proof).expect("Valid gindex")
res.add(sidecar)
res

# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/altair/light-client/sync-protocol.md#is_sync_committee_update
template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool =
when update is SomeForkyLightClientUpdateWithSyncCommittee:
Expand Down
34 changes: 3 additions & 31 deletions beacon_chain/spec/mev/deneb_mev.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,10 @@ from stew/byteutils import to0xHex
from ".."/datatypes/capella import SignedBLSToExecutionChange

type
# https://github.com/ethereum/builder-specs/blob/534e4f81276b8346d785ed9aba12c4c74b927ec6/specs/deneb/builder.md#blindedblobsbundle
BlindedBlobsBundle* = object
commitments*: List[KZGCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
proofs*: List[KZGProof, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
blob_roots*: List[Eth2Digest, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]

# https://github.com/ethereum/builder-specs/blob/534e4f81276b8346d785ed9aba12c4c74b927ec6/specs/deneb/builder.md#builderbid
BuilderBid* = object
header*: deneb.ExecutionPayloadHeader # [Modified in Deneb]
blinded_blobs_bundle*: BlindedBlobsBundle # [New in Deneb]
blob_kzg_commitments*: KzgCommitments # [New in Deneb]
value*: UInt256
pubkey*: ValidatorPubKey

Expand Down Expand Up @@ -67,30 +61,15 @@ type
message*: BlindedBeaconBlock
signature*: ValidatorSig

# https://github.com/ethereum/builder-specs/blob/534e4f81276b8346d785ed9aba12c4c74b927ec6/specs/deneb/builder.md#blindedblobsidecar
BlindedBlobSidecar* = object
index*: uint64
blob_root*: Eth2Digest
kzg_commitment*: KZGCommitment
kzg_proof*: KZGProof
signed_block_header*: SignedBeaconBlockHeader
kzg_commitment_inclusion_proof*:
array[KZG_COMMITMENT_INCLUSION_PROOF_DEPTH, Eth2Digest]

# https://github.com/ethereum/builder-specs/blob/534e4f81276b8346d785ed9aba12c4c74b927ec6/specs/deneb/builder.md#signedblindedblockcontents
SignedBlindedBeaconBlockContents* = object
signed_blinded_block*: deneb_mev.SignedBlindedBeaconBlock
blinded_blob_sidecars*: List[BlindedBlobSidecar, Limit MAX_BLOBS_PER_BLOCK]

# https://github.com/ethereum/builder-specs/blob/534e4f81276b8346d785ed9aba12c4c74b927ec6/specs/deneb/builder.md#executionpayloadandblobsbundle
ExecutionPayloadAndBlobsBundle* = object
execution_payload*: deneb.ExecutionPayload
blobs_bundle*: BlobsBundle

# Not spec, but suggested by spec
ExecutionPayloadHeaderAndBlindedBlobsBundle* = object
BlindedExecutionPayloadAndBlobsBundle* = object
execution_payload_header*: deneb.ExecutionPayloadHeader
blinded_blobs_bundle*: BlindedBlobsBundle
blob_kzg_commitments*: KzgCommitments # [New in Deneb]

func shortLog*(v: BlindedBeaconBlock): auto =
(
Expand Down Expand Up @@ -118,10 +97,3 @@ func shortLog*(v: SignedBlindedBeaconBlock): auto =
blck: shortLog(v.message),
signature: shortLog(v.signature)
)

# needs to match SignedBlindedBeaconBlock
func shortLog*(v: SignedBlindedBeaconBlockContents): auto =
(
blck: shortLog(v.signed_blinded_block.message),
signature: shortLog(v.signed_blinded_block.signature)
)
2 changes: 1 addition & 1 deletion beacon_chain/spec/mev/rest_deneb_mev_calls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ proc getHeaderDeneb*(slot: Slot,
meth: MethodGet, connection: {Dedicated, Close}.}
## https://github.com/ethereum/builder-specs/blob/34509da74237942aa15a4c0ca828f67acdf77652/apis/builder/header.yaml

proc submitBlindedBlock*(body: deneb_mev.SignedBlindedBeaconBlockContents
proc submitBlindedBlock*(body: deneb_mev.SignedBlindedBeaconBlock
): RestResponse[SubmitBlindedBlockResponseDeneb] {.
rest, endpoint: "/eth/v1/builder/blinded_blocks",
meth: MethodPost, connection: {Dedicated, Close}.}
Expand Down
Loading