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

Initial commit for eip-7732 on fulu #6768

Draft
wants to merge 4 commits into
base: fulu
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion beacon_chain/consensus_object_pools/blob_quarantine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func popBlobs*(
fulu.SignedBeaconBlock): seq[ref BlobSidecar] =
var r: seq[ref BlobSidecar] = @[]

# Handle `fulu` blocks: skip processing blobs
# skip processing blobs for fulu
when typeof(blck).kind == ConsensusFork.Fulu:
return r
else:
Expand Down
13 changes: 8 additions & 5 deletions beacon_chain/gossip_processing/gossip_validation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,14 @@ template validateBeaconBlockBellatrix(
withState(dag.headState):
compute_timestamp_at_slot(
forkyState.data, signed_beacon_block.message.slot)
if not (signed_beacon_block.message.body.execution_payload.timestamp ==
timestampAtSlot):
quarantine[].addUnviable(signed_beacon_block.root)
return dag.checkedReject(
"BeaconBlock: mismatched execution payload timestamp")
when signed_beacon_block is fulu.SignedBeaconBlock:
Copy link

@shyam-patel-kira shyam-patel-kira Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we discarding a signed_beacon_block from fulu here? If a block belongs to fulu it shouldn't enter validateBeaconBlockBellatrix, right? Or am I missing something?

Copy link
Contributor Author

@Tomi-3-0 Tomi-3-0 Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validateBeaconBlockBellatrix is a generic template to allow code reuse while maintaining type safety, accepting multiple SignedBeaconBlock types from Bellatrix upwards.

Since fulu blocks have had the execution_payload removed from their beaconblocks, we need to handle them explicitly with when signed_beacon_block is fulu.SignedBeaconBlock: discard to skip the timestamp validation that depends on the execution payload

discard
else:
if not (signed_beacon_block.message.body.execution_payload.timestamp ==
timestampAtSlot):
quarantine[].addUnviable(signed_beacon_block.root)
return dag.checkedReject(
"BeaconBlock: mismatched execution payload timestamp")

# The condition:
# [REJECT] The block's parent (defined by `block.parent_root`) passes all
Expand Down
49 changes: 30 additions & 19 deletions beacon_chain/spec/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -231,25 +231,36 @@ func create_blob_sidecars*(
fulu.SignedBeaconBlock,
kzg_proofs: KzgProofs,
blobs: Blobs): seq[BlobSidecar] =
template kzg_commitments: untyped =
forkyBlck.message.body.blob_kzg_commitments
doAssert kzg_proofs.len == blobs.len
doAssert kzg_proofs.len == kzg_commitments.len

var res = newSeqOfCap[BlobSidecar](blobs.len)
let signedBlockHeader = forkyBlck.toSignedBeaconBlockHeader()
for i in 0 ..< blobs.lenu64:
var sidecar = BlobSidecar(
index: i,
blob: blobs[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

when forkyBlck is fulu.SignedBeaconBlock:
return @[]
else:
template kzg_commitments: untyped =
forkyBlck.message.body.blob_kzg_commitments

if kzg_proofs.len == 0 or blobs.len == 0 or kzg_commitments.len == 0:
return @[]

doAssert kzg_proofs.len == blobs.len
doAssert kzg_proofs.len == kzg_commitments.len

var res = newSeqOfCap[BlobSidecar](blobs.len)
let signedBlockHeader = forkyBlck.toSignedBeaconBlockHeader()

if blobs.len > 0:
for i in 0 ..< blobs.lenu64:
var sidecar = BlobSidecar(
index: i,
blob: blobs[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.5.0-alpha.5/specs/altair/light-client/sync-protocol.md#is_sync_committee_update
template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool =
Expand Down
21 changes: 13 additions & 8 deletions beacon_chain/sync/sync_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,15 @@ proc getSyncBlockData*[T](
let (shouldGetBlob, blobsCount) =
withBlck(blocksRange[0][]):
when consensusFork >= ConsensusFork.Deneb:
let res = len(forkyBlck.message.body.blob_kzg_commitments)
if res > 0:
(true, res)
else:
when consensusFork == ConsensusFork.Fulu:
# Fulu fork: No blob-related fields
(false, 0)
else:
let res = len(forkyBlck.message.body.blob_kzg_commitments)
if res > 0:
(true, res)
else:
(false, 0)
else:
(false, 0)

Expand Down Expand Up @@ -528,10 +532,11 @@ proc syncStep[A, B](
var hasBlobs = false
for blck in blockData:
withBlck(blck[]):
when consensusFork >= ConsensusFork.Deneb:
if forkyBlck.message.body.blob_kzg_commitments.len > 0:
hasBlobs = true
break
when consensusFork >= ConsensusFork.Deneb and
consensusFork != ConsensusFork.Fulu:
if forkyBlck.message.body.blob_kzg_commitments.len > 0:
hasBlobs = true
break
hasBlobs

let blobData =
Expand Down
59 changes: 41 additions & 18 deletions beacon_chain/validators/beacon_validators.nim
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,17 @@ func constructSignableBlindedBlock[T: electra_mev.SignedBlindedBeaconBlock |
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/validator.md#block-proposal
copyFields(blindedBlock.message, blck, blckFields)
copyFields(blindedBlock.message.body, blck.body, blckBodyFields)
assign(
blindedBlock.message.body.execution_payload_header,
blindedBundle.execution_payload_header)
assign(
blindedBlock.message.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments)
when T is fulu_mev.SignedBlindedBeaconBlock:
assign(
blindedBlock.message.body.signed_execution_payload_header,
blindedBundle.execution_payload_header)
else:
assign(
blindedBlock.message.body.execution_payload_header,
blindedBundle.execution_payload_header)
assign(
blindedBlock.message.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments)

blindedBlock

Expand All @@ -753,12 +758,19 @@ func constructSignableBlindedBlock[T: fulu_mev.SignedBlindedBeaconBlock](
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/validator.md#block-proposal
copyFields(blindedBlock.message, blck, blckFields)
copyFields(blindedBlock.message.body, blck.body, blckBodyFields)
assign(
blindedBlock.message.body.execution_payload_header,
blindedBundle.execution_payload_header)
assign(
blindedBlock.message.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments)

when T is fulu_mev.SignedBlindedBeaconBlock:
assign(
blindedBlock.message.body.signed_execution_payload_header.message,
blindedBundle.execution_payload_header)
else:
assign(
blindedBlock.message.body.execution_payload_header,
blindedBundle.execution_payload_header)
assign(
blindedBlock.message.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments)


blindedBlock

Expand Down Expand Up @@ -826,11 +838,11 @@ func constructPlainBlindedBlock[T: fulu_mev.BlindedBeaconBlock](
copyFields(blindedBlock, blck, blckFields)
copyFields(blindedBlock.body, blck.body, blckBodyFields)
assign(
blindedBlock.body.execution_payload_header,
blindedBlock.body.signed_execution_payload_header.message,
blindedBundle.execution_payload_header)
assign(
blindedBlock.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments)
# assign(
# blindedBlock.body.blob_kzg_commitments,
# blindedBundle.blob_kzg_commitments)

blindedBlock

Expand Down Expand Up @@ -997,7 +1009,10 @@ proc getBlindedBlockParts[
let newBlock = await makeBeaconBlockForHeadAndSlot(
PayloadType, node, randao, validator_index, graffiti, head, slot,
execution_payload = Opt.some shimExecutionPayload,
transactions_root = Opt.some actualEPH.transactions_root,
transactions_root = when compiles(actualEPH.withdrawals_root):
Opt.some(actualEPH.withdrawals_root)
else:
Opt.none(Eth2Digest),
execution_payload_root = Opt.some hash_tree_root(actualEPH),
withdrawals_root = withdrawals_root,
kzg_commitments = kzg_commitments,
Expand Down Expand Up @@ -2215,7 +2230,7 @@ proc makeMaybeBlindedBeaconBlockForHeadAndSlotImpl[ResultType](

doAssert engineBid.blck.kind == consensusFork
template forkyBlck: untyped = engineBid.blck.forky(consensusFork)
when consensusFork >= ConsensusFork.Deneb:
when consensusFork >= ConsensusFork.Deneb and consensusFork != ConsensusFork.Fulu:
let blobsBundle = engineBid.blobsBundleOpt.get()
doAssert blobsBundle.commitments == forkyBlck.body.blob_kzg_commitments
ResultType.ok((
Expand All @@ -2227,6 +2242,14 @@ proc makeMaybeBlindedBeaconBlockForHeadAndSlotImpl[ResultType](
blobs: blobsBundle.blobs)),
executionValue: Opt.some(engineBid.executionPayloadValue),
consensusValue: Opt.some(engineBid.consensusBlockValue)))
elif consensusFork == ConsensusFork.Fulu:
# Fulu fork: no blobs or KZG commitments
ResultType.ok((
blck: consensusFork.MaybeBlindedBeaconBlock(
isBlinded: false,
data: consensusFork.BlockContents(`block`: forkyBlck)),
executionValue: Opt.some(engineBid.executionPayloadValue),
consensusValue: Opt.some(engineBid.consensusBlockValue)))
else:
ResultType.ok((
blck: consensusFork.MaybeBlindedBeaconBlock(
Expand Down
4 changes: 3 additions & 1 deletion beacon_chain/validators/message_router.nim
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ proc routeSignedBeaconBlock*(
signature = shortLog(blck.signature), error = res.error()
return err($(res.error()[1]))

when typeof(blck).kind >= ConsensusFork.Deneb:
when typeof(blck).kind == ConsensusFork.Fulu:
discard
elif typeof(blck).kind >= ConsensusFork.Deneb:
if blobsOpt.isSome:
let blobs = blobsOpt.get()
let kzgCommits = blck.message.body.blob_kzg_commitments.asSeq
Expand Down
31 changes: 23 additions & 8 deletions beacon_chain/validators/message_router_mev.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ macro copyFields*(
# unblinded objects, and can't simply be copied.
"transactions_root", "execution_payload",
"execution_payload_header", "body", "withdrawals_root",
"deposit_requests_root", "withdrawal_requests_root",
"parent_block_hash", "parent_block_root", "builder_index",
"value", "blob_kzg_commitments_root","payload_attestations",
"deposit_requests_root", "withdrawal_requests_root", "slot",
"consolidation_requests_root"]:
# TODO use stew/assign2
result.add newAssignment(
Expand Down Expand Up @@ -104,11 +106,17 @@ proc unblindAndRouteBlockMEV*(
$response.contentType & " and content " & $response.data)

template execution_payload: untyped = bundle.data.execution_payload

if hash_tree_root(blindedBlock.message.body.execution_payload_header) !=
hash_tree_root(execution_payload):
return err("unblinded payload doesn't match blinded payload header: " &
$blindedBlock.message.body.execution_payload_header)

when blindedBlock is fulu_mev.SignedBlindedBeaconBlock:
if hash_tree_root(blindedBlock.message.body.signed_execution_payload_header.message) !=
hash_tree_root(execution_payload):
return err("unblinded payload doesn't match blinded payload header: " &
$blindedBlock.message.body.signed_execution_payload_header)
else:
if hash_tree_root(blindedBlock.message.body.execution_payload_header) !=
hash_tree_root(execution_payload):
return err("unblinded payload doesn't match blinded payload header: " &
$blindedBlock.message.body.execution_payload_header)

# Signature provided is consistent with unblinded execution payload,
# so construct full beacon block
Expand All @@ -121,12 +129,19 @@ proc unblindAndRouteBlockMEV*(
copyFields(
signedBlock.message.body, blindedBlock.message.body,
getFieldNames(typeof(signedBlock.message.body)))
assign(signedBlock.message.body.execution_payload, execution_payload)
when blindedBlock is fulu_mev.SignedBlindedBeaconBlock:
discard
else:
assign(signedBlock.message.body.execution_payload, bundle.data.execution_payload)

# assign(signedBlock.message.body.execution_payload, execution_payload)
signedBlock.root = hash_tree_root(signedBlock.message)
doAssert signedBlock.root == hash_tree_root(blindedBlock.message)

let blobsOpt =
when consensusFork >= ConsensusFork.Deneb:
when consensusFork >= ConsensusFork.Fulu:
Opt.none(seq[BlobSidecar])
elif consensusFork >= ConsensusFork.Deneb:
template blobs_bundle: untyped = bundle.data.blobs_bundle
if blindedBlock.message.body.blob_kzg_commitments !=
bundle.data.blobs_bundle.commitments:
Expand Down
Loading