Skip to content
Draft
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
141 changes: 101 additions & 40 deletions beacon_chain/gossip_processing/gossip_validation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,7 @@ func getMaxBlobsPerBlock(cfg: RuntimeConfig, slot: Slot): uint64 =
else:
cfg.MAX_BLOBS_PER_BLOCK

debugGloasComment ""
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.0/specs/gloas/p2p-interface.md#beacon_block
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/p2p-interface.md#beacon_block
template validateBeaconBlockBellatrix(
_: phase0.SignedBeaconBlock | altair.SignedBeaconBlock | gloas.SignedBeaconBlock,
_: BlockRef): untyped =
Expand Down Expand Up @@ -367,8 +366,7 @@ template validateBeaconBlockBellatrix(
# cannot occur here, because Nimbus's optimistic sync waits for either
# `ACCEPTED` or `SYNCING` from the EL to get this far.

debugGloasComment ""
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.0/specs/gloas/p2p-interface.md#beacon_block
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/p2p-interface.md#beacon_block
template validateBeaconBlockDeneb(
_: ChainDAGRef,
_:
Expand All @@ -394,6 +392,51 @@ template validateBeaconBlockDeneb(
blob_params.MAX_BLOBS_PER_BLOCK):
return dag.checkedReject("validateBeaconBlockDeneb: too many blob commitments")

template validateBeaconBlockGloas(
_: ChainDAGRef,
_:
phase0.SignedBeaconBlock | altair.SignedBeaconBlock |
bellatrix.SignedBeaconBlock | capella.SignedBeaconBlock |
deneb.SignedBeaconBlock | electra.SignedBeaconBlock |
fulu.SignedBeaconBlock,
_: BlockRef): untyped =
discard

# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/p2p-interface.md#beacon_block
template validateBeaconBlockGloas(
dag: ChainDAGRef,
signed_beacon_block: gloas.SignedBeaconBlock,
parent: BlockRef): untyped =
template blck: untyped = signed_beacon_block.message
template bid: untyped = blck.body.signed_execution_payload_bid.message

# If `execution_payload` verification of block's execution payload parent by
# an execution node **is complete**
debugGloasComment("")
let isExecutionEnabled =
if signed_beacon_block.message.is_execution_block:
true
else:
# If we don't know whether the parent block had execution enabled,
# assume it didn't. This way, we don't reject here if the timestamp
# is invalid, and let state transition check the timestamp.
# This is an edge case, and may be hit in a pathological scenario with
# checkpoint sync, because the checkpoint block may be unavailable
# and it could already be the parent of the new block before backfill.
not dag.loadExecutionBlockHash(parent).get(ZERO_HASH).isZero
if isExecutionEnabled:
# [REJECT] The block's execution payload parent (defined by
# `bid.parent_block_hash`) passes all validation.
withState(dag.headState):
when consensusFork >= ConsensusFork.Gloas:
if bid.parent_block_hash != forkyState.data.latest_block_hash:
return dag.checkedReject("validateBeaconBlockGloas: invalid execution payload parent")

# [REJECT] The bid's parent (defined by `bid.parent_block_root`) equals the
# block's parent (defined by `block.parent_root`).
if bid.parent_block_root != blck.parent_root:
return dag.checkedReject("validateBeaconBlockGloas: parent block root mismatch")

# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/deneb/p2p-interface.md#blob_sidecar_subnet_id
proc validateBlobSidecar*(
dag: ChainDAGRef, quarantine: ref Quarantine,
Expand Down Expand Up @@ -779,6 +822,7 @@ proc validateDataColumnSidecar*(

# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#beacon_block
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#beacon_block
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/p2p-interface.md#beacon_block
proc validateBeaconBlock*(
dag: ChainDAGRef, quarantine: ref Quarantine,
signed_beacon_block: ForkySignedBeaconBlock,
Expand Down Expand Up @@ -857,43 +901,58 @@ proc validateBeaconBlock*(
if signed_beacon_block.message.parent_root in quarantine[].unviable:
quarantine[].addUnviable(signed_beacon_block.root)

# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#beacon_block
# `is_execution_enabled(state, block.body)` check, but unlike in
# validateBeaconBlockBellatrix() don't have parent BlockRef.
if signed_beacon_block.message.is_execution_block:
# Blocks with execution enabled will be permitted to propagate
# regardless of the validity of the execution payload. This prevents
# network segregation between optimistic and non-optimistic nodes.
#
# If execution_payload verification of block's parent by an execution
# node is not complete:
#
# - [REJECT] The block's parent (defined by `block.parent_root`) passes
# all validation (excluding execution node verification of the
# `block.body.execution_payload`).
#
# otherwise:
#
# - [IGNORE] The block's parent (defined by `block.parent_root`) passes
# all validation (including execution node verification of the
# `block.body.execution_payload`).

# Implementation restrictions:
#
# - We don't know if the parent state had execution enabled.
# If it had, and the block doesn't have it enabled anymore,
# we end up in the pre-Merge path below (`else`) and REJECT.
# Such a block is clearly invalid, though, without asking the EL.
#
# - We know that the parent was marked unviable, but don't know
# whether it was marked unviable due to consensus (REJECT) or
# execution (IGNORE) verification failure. We err on the IGNORE side.
return errIgnore("BeaconBlock: ignored, parent from unviable fork")
when type(signed_beacon_block).kind >= ConsensusFork.Gloas:
# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/p2p-interface.md#beacon_block
# some validations removed so we only need to check
if signed_beacon_block.message.is_execution_block:
# - [REJECT] The block's parent (defined by `block.parent_root`) passes
# all validation (excluding execution node verification of the
# `block.body.execution_payload`).
#
# otherwise:
#
# - [IGNORE] The block's parent (defined by `block.parent_root`) passes
# all validation (including execution node verification of the
# `block.body.execution_payload`).
return errIgnore("BeaconBlock: ignored, parent from unviable fork")
else:
# [REJECT] The block's parent (defined by `block.parent_root`) passes
# validation.
return dag.checkedReject(
"BeaconBlock: rejected, parent from unviable fork")
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#beacon_block
# `is_execution_enabled(state, block.body)` check, but unlike in
# validateBeaconBlockBellatrix() don't have parent BlockRef.
if signed_beacon_block.message.is_execution_block:
# Blocks with execution enabled will be permitted to propagate
# regardless of the validity of the execution payload. This prevents
# network segregation between optimistic and non-optimistic nodes.
#
# If execution_payload verification of block's parent by an execution
# node is not complete:
#
# - [REJECT] The block's parent (defined by `block.parent_root`) passes
# all validation (excluding execution node verification of the
# `block.body.execution_payload`).
#
# otherwise:
#
# - [IGNORE] The block's parent (defined by `block.parent_root`) passes
# all validation (including execution node verification of the
# `block.body.execution_payload`).

# Implementation restrictions:
#
# - We don't know if the parent state had execution enabled.
# If it had, and the block doesn't have it enabled anymore,
# we end up in the pre-Merge path below (`else`) and REJECT.
# Such a block is clearly invalid, though, without asking the EL.
#
# - We know that the parent was marked unviable, but don't know
# whether it was marked unviable due to consensus (REJECT) or
# execution (IGNORE) verification failure. We err on the IGNORE side.
return errIgnore("BeaconBlock: ignored, parent from unviable fork")
else:
# [REJECT] The block's parent (defined by `block.parent_root`) passes
# validation.
return dag.checkedReject(
"BeaconBlock: rejected, parent from unviable fork")

# When the parent is missing, we can't validate the block - we'll queue it
# in the quarantine for later processing
Expand All @@ -918,6 +977,8 @@ proc validateBeaconBlock*(

dag.validateBeaconBlockDeneb(signed_beacon_block, wallTime)

dag.validateBeaconBlockGloas(signed_beacon_block, parent)

# [REJECT] The block is from a higher slot than its parent.
if not (signed_beacon_block.message.slot > parent.bid.slot):
return dag.checkedReject(
Expand Down
Loading