Skip to content

Commit

Permalink
update Deneb for latest builder-specs flow
Browse files Browse the repository at this point in the history
The `BlobSidecar` construction has been moved to the relay and is no
longer done by the BN / VC in blinded flow. Builder bid contents have
been shrinked from full `BlindedBlobBundle` to `blob_kzg_commitments`.

- ethereum/builder-specs#90
- ethereum/beacon-APIs#369
  • Loading branch information
etan-status committed Nov 13, 2023
1 parent 2f0bb61 commit e9ebb46
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 351 deletions.
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

0 comments on commit e9ebb46

Please sign in to comment.