wrap `kzgs`/`proofs`/`blobs` fields as `BlobsBundle` (#5562)

Less type conversion / copying by keeping the `BlobsBundle` together.
This commit is contained in:
Etan Kissling 2023-11-04 14:49:58 +01:00 committed by GitHub
parent fb18f09e55
commit a05278e263
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 56 deletions

View File

@ -551,10 +551,13 @@ func asConsensusType*(payload: engine_api.GetPayloadV3Response):
# The `mapIt` calls below are necessary only because we use different distinct # The `mapIt` calls below are necessary only because we use different distinct
# types for KZG commitments and Blobs in the `web3` and the `deneb` spec types. # types for KZG commitments and Blobs in the `web3` and the `deneb` spec types.
# Both are defined as `array[N, byte]` under the hood. # Both are defined as `array[N, byte]` under the hood.
kzgs: KzgCommitments payload.blobsBundle.commitments.mapIt(it.bytes), blobsBundle: BlobsBundle(
proofs: payload.blobsBundle.proofs.mapIt(it.bytes), commitments: KzgCommitments.init(
blobs: Blobs payload.blobsBundle.blobs.mapIt(it.bytes) payload.blobsBundle.commitments.mapIt(it.bytes)),
) proofs: KzgProofs.init(
payload.blobsBundle.proofs.mapIt(it.bytes)),
blobs: Blobs.init(
payload.blobsBundle.blobs.mapIt(it.bytes))))
func asEngineExecutionPayload*(executionPayload: bellatrix.ExecutionPayload): func asEngineExecutionPayload*(executionPayload: bellatrix.ExecutionPayload):
ExecutionPayloadV1 = ExecutionPayloadV1 =

View File

@ -392,21 +392,13 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
qslot, proposer, qrandao, qskip_randao_verification): qslot, proposer, qrandao, qskip_randao_verification):
return RestApiResponse.jsonError(Http400, InvalidRandaoRevealValue) return RestApiResponse.jsonError(Http400, InvalidRandaoRevealValue)
let res = let res = withConsensusFork(
case node.dag.cfg.consensusForkAtEpoch(qslot.epoch) node.dag.cfg.consensusForkAtEpoch(qslot.epoch)):
of ConsensusFork.Deneb: when consensusFork >= ConsensusFork.Bellatrix:
await makeBeaconBlockForHeadAndSlot( await makeBeaconBlockForHeadAndSlot(
deneb.ExecutionPayloadForSigning, consensusFork.ExecutionPayloadForSigning,
node, qrandao, proposer, qgraffiti, qhead, qslot) node, qrandao, proposer, qgraffiti, qhead, qslot)
of ConsensusFork.Capella: else:
await makeBeaconBlockForHeadAndSlot(
capella.ExecutionPayloadForSigning,
node, qrandao, proposer, qgraffiti, qhead, qslot)
of ConsensusFork.Bellatrix:
await makeBeaconBlockForHeadAndSlot(
bellatrix.ExecutionPayloadForSigning,
node, qrandao, proposer, qgraffiti, qhead, qslot)
of ConsensusFork.Altair, ConsensusFork.Phase0:
return RestApiResponse.jsonError(Http400, InvalidSlotValueError) return RestApiResponse.jsonError(Http400, InvalidSlotValueError)
if res.isErr(): if res.isErr():
return RestApiResponse.jsonError(Http400, res.error()) return RestApiResponse.jsonError(Http400, res.error())
@ -414,7 +406,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
return return
withBlck(message.blck): withBlck(message.blck):
let data = let data =
when forkyBlck is deneb.BeaconBlock: when consensusFork >= ConsensusFork.Deneb:
let bundle = message.blobsBundleOpt.get() let bundle = message.blobsBundleOpt.get()
let blockRoot = hash_tree_root(forkyBlck) let blockRoot = hash_tree_root(forkyBlck)
var sidecars = newSeqOfCap[BlobSidecar](bundle.blobs.len) var sidecars = newSeqOfCap[BlobSidecar](bundle.blobs.len)
@ -426,7 +418,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
block_parent_root: forkyBlck.parent_root, block_parent_root: forkyBlck.parent_root,
proposer_index: forkyBlck.proposer_index, proposer_index: forkyBlck.proposer_index,
blob: bundle.blobs[i], blob: bundle.blobs[i],
kzg_commitment: bundle.kzgs[i], kzg_commitment: bundle.commitments[i],
kzg_proof: bundle.proofs[i] kzg_proof: bundle.proofs[i]
) )
sidecars.add(sidecar) sidecars.add(sidecar)
@ -435,18 +427,13 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
`block`: forkyBlck, `block`: forkyBlck,
blob_sidecars: List[BlobSidecar, blob_sidecars: List[BlobSidecar,
Limit MAX_BLOBS_PER_BLOCK].init(sidecars)) Limit MAX_BLOBS_PER_BLOCK].init(sidecars))
elif forkyBlck is phase0.BeaconBlock or
forkyBlck is altair.BeaconBlock or
forkyBlck is bellatrix.BeaconBlock or
forkyBlck is capella.BeaconBlock:
forkyBlck
else: else:
static: raiseAssert "produceBlockV2 received unexpected version" forkyBlck
if contentType == sszMediaType: if contentType == sszMediaType:
let headers = [("eth-consensus-version", message.blck.kind.toString())] let headers = [("eth-consensus-version", consensusFork.toString())]
RestApiResponse.sszResponse(data, headers) RestApiResponse.sszResponse(data, headers)
elif contentType == jsonMediaType: elif contentType == jsonMediaType:
RestApiResponse.jsonResponseWVersion(data, message.blck.kind) RestApiResponse.jsonResponseWVersion(data, consensusFork)
else: else:
raiseAssert "preferredContentType() returns invalid content type" raiseAssert "preferredContentType() returns invalid content type"

View File

@ -38,6 +38,7 @@ const
type type
KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK] KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
KzgProofs* = List[KzgProof, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
Blobs* = List[Blob, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK] Blobs* = List[Blob, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
# TODO this apparently is suppposed to be SSZ-equivalent to Bytes32, but # TODO this apparently is suppposed to be SSZ-equivalent to Bytes32, but
@ -50,6 +51,12 @@ type
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.2/specs/deneb/polynomial-commitments.md#custom-types # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.2/specs/deneb/polynomial-commitments.md#custom-types
Blob* = array[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB, byte] Blob* = array[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB, byte]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/deneb/validator.md#blobsbundle
BlobsBundle* = object
commitments*: KzgCommitments
proofs*: KzgProofs
blobs*: Blobs
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.3/specs/deneb/p2p-interface.md#blobsidecar # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.3/specs/deneb/p2p-interface.md#blobsidecar
BlobSidecar* = object BlobSidecar* = object
block_root*: Eth2Digest block_root*: Eth2Digest
@ -103,9 +110,7 @@ type
ExecutionPayloadForSigning* = object ExecutionPayloadForSigning* = object
executionPayload*: ExecutionPayload executionPayload*: ExecutionPayload
blockValue*: Wei blockValue*: Wei
kzgs*: KzgCommitments blobsBundle*: BlobsBundle
proofs*: seq[KZGProof]
blobs*: Blobs
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.3/specs/deneb/beacon-chain.md#executionpayloadheader # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.3/specs/deneb/beacon-chain.md#executionpayloadheader
ExecutionPayloadHeader* = object ExecutionPayloadHeader* = object
@ -131,12 +136,6 @@ type
blob_gas_used*: uint64 # [New in Deneb:EIP4844] blob_gas_used*: uint64 # [New in Deneb:EIP4844]
excess_blob_gas*: uint64 # [New in Deneb:EIP4844] excess_blob_gas*: uint64 # [New in Deneb:EIP4844]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.3/specs/deneb/validator.md#blobsbundle
BlobsBundle* = object
commitments*: seq[KZGCommitment]
proofs*: seq[KZGProof]
blobs*: seq[Blob]
ExecutePayload* = proc( ExecutePayload* = proc(
execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].} execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].}

View File

@ -380,7 +380,7 @@ func partialBeaconBlock*(
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/validator.md#constructing-the-beaconblockbody # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/validator.md#constructing-the-beaconblockbody
when consensusFork >= ConsensusFork.Deneb: when consensusFork >= ConsensusFork.Deneb:
res.body.blob_kzg_commitments = execution_payload.kzgs res.body.blob_kzg_commitments = execution_payload.blobsBundle.commitments
res res

View File

@ -292,7 +292,7 @@ proc getMissingBlobs(rman: RequestManager): seq[BlobIdentifier] =
warn "quarantine missing blobs, but missing indices is empty", warn "quarantine missing blobs, but missing indices is empty",
blk=blobless.root, blk=blobless.root,
indices=rman.blobQuarantine[].blobIndices(blobless.root), indices=rman.blobQuarantine[].blobIndices(blobless.root),
kzgs=len(blobless.message.body.blob_kzg_commitments) commitments=len(blobless.message.body.blob_kzg_commitments)
for idx in missing.indices: for idx in missing.indices:
let id = BlobIdentifier(block_root: blobless.root, index: idx) let id = BlobIdentifier(block_root: blobless.root, index: idx)
if id notin fetches: if id notin fetches:
@ -302,7 +302,7 @@ proc getMissingBlobs(rman: RequestManager): seq[BlobIdentifier] =
warn "missing blob handler found blobless block with all blobs", warn "missing blob handler found blobless block with all blobs",
blk=blobless.root, blk=blobless.root,
indices=rman.blobQuarantine[].blobIndices(blobless.root), indices=rman.blobQuarantine[].blobIndices(blobless.root),
kzgs=len(blobless.message.body.blob_kzg_commitments) commitments=len(blobless.message.body.blob_kzg_commitments)
discard rman.blockVerifier(ForkedSignedBeaconBlock.init(blobless), discard rman.blockVerifier(ForkedSignedBeaconBlock.init(blobless),
false) false)
rman.quarantine[].removeBlobless(blobless) rman.quarantine[].removeBlobless(blobless)
@ -356,4 +356,3 @@ proc stop*(rman: RequestManager) =
rman.blockLoopFuture.cancelSoon() rman.blockLoopFuture.cancelSoon()
if not(isNil(rman.blobLoopFuture)): if not(isNil(rman.blobLoopFuture)):
rman.blobLoopFuture.cancelSoon() rman.blobLoopFuture.cancelSoon()

View File

@ -88,9 +88,6 @@ declarePublicGauge(attached_validator_balance_total,
logScope: topics = "beacval" logScope: topics = "beacval"
type type
BlobsBundle = tuple[blobs: deneb.Blobs,
kzgs: KzgCommitments,
proofs: seq[kzg_abi.KZGProof]]
ForkedBlockResult = ForkedBlockResult =
Result[tuple[blck: ForkedBeaconBlock, Result[tuple[blck: ForkedBeaconBlock,
blockValue: Wei, blockValue: Wei,
@ -541,10 +538,7 @@ proc makeBeaconBlockForHeadAndSlot*(
var blobsBundleOpt = Opt.none(BlobsBundle) var blobsBundleOpt = Opt.none(BlobsBundle)
when payload is deneb.ExecutionPayloadForSigning: when payload is deneb.ExecutionPayloadForSigning:
let bb: BlobsBundle = (blobs: payload.blobs, blobsBundleOpt = Opt.some(payload.blobsBundle)
kzgs: payload.kzgs,
proofs: payload.proofs)
blobsBundleOpt = Opt.some(bb)
return if blck.isOk: return if blck.isOk:
ok((blck.get, payload.blockValue, blobsBundleOpt)) ok((blck.get, payload.blockValue, blobsBundleOpt))
else: else:
@ -1176,10 +1170,11 @@ proc proposeBlockAux(
.registerBlock(validator_index, validator.pubkey, slot, signingRoot) .registerBlock(validator_index, validator.pubkey, slot, signingRoot)
let blobSidecarsOpt = let blobSidecarsOpt =
when forkyBlck is deneb.BeaconBlock: when consensusFork >= ConsensusFork.Deneb:
var sidecars: seq[BlobSidecar] var sidecars: seq[BlobSidecar]
let bundle = collectedBids.engineBlockFut.read.get().blobsBundleOpt.get let bundle = collectedBids.engineBlockFut.read.get().blobsBundleOpt.get
let (blobs, kzgs, proofs) = (bundle.blobs, bundle.kzgs, bundle.proofs) let (blobs, commitments, proofs) = (
bundle.blobs, bundle.commitments, bundle.proofs)
for i in 0..<blobs.len: for i in 0..<blobs.len:
var sidecar = BlobSidecar( var sidecar = BlobSidecar(
block_root: blockRoot, block_root: blockRoot,
@ -1188,18 +1183,13 @@ proc proposeBlockAux(
block_parent_root: forkyBlck.parent_root, block_parent_root: forkyBlck.parent_root,
proposer_index: forkyBlck.proposer_index, proposer_index: forkyBlck.proposer_index,
blob: blobs[i], blob: blobs[i],
kzg_commitment: kzgs[i], kzg_commitment: commitments[i],
kzg_proof: proofs[i] kzg_proof: proofs[i]
) )
sidecars.add(sidecar) sidecars.add(sidecar)
Opt.some(sidecars) Opt.some(sidecars)
elif forkyBlck is phase0.BeaconBlock or
forkyBlck is altair.BeaconBlock or
forkyBlck is bellatrix.BeaconBlock or
forkyBlck is capella.BeaconBlock:
Opt.none(seq[BlobSidecar])
else: else:
static: doAssert "Unknown BeaconBlock type" Opt.none(seq[BlobSidecar])
if notSlashable.isErr: if notSlashable.isErr:
warn "Slashing protection activated for block proposal", warn "Slashing protection activated for block proposal",