update gossip validation for v1.4.0-beta.0 (#5133)

Co-authored-by: Etan Kissling <etan@status.im>
This commit is contained in:
tersec 2023-06-29 08:34:21 +00:00 committed by GitHub
parent 7b0e3b1c04
commit dc5687093f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 33 deletions

View File

@ -82,25 +82,55 @@ func check_attestation_block(
ok() ok()
func check_propagation_slot_range( func check_propagation_slot_range(
msgSlot: Slot, wallTime: BeaconTime): Result[Slot, ValidationError] = consensusFork: ConsensusFork, msgSlot: Slot, wallTime: BeaconTime):
let Result[Slot, ValidationError] =
futureSlot = (wallTime + MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot() let futureSlot = (wallTime + MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
if not futureSlot.afterGenesis or msgSlot > futureSlot.slot: if not futureSlot.afterGenesis or msgSlot > futureSlot.slot:
return errIgnore("Attestation slot in the future") return errIgnore("Attestation slot in the future")
let let pastSlot = (wallTime - MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
pastSlot = (wallTime - MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/phase0/p2p-interface.md#configuration if not pastSlot.afterGenesis:
# The spec value of ATTESTATION_PROPAGATION_SLOT_RANGE is 32, but it can return ok(msgSlot)
# retransmit attestations on the cusp of being out of spec, and which by
# the time they reach their destination might be out of spec.
const ATTESTATION_PROPAGATION_SLOT_RANGE = 28
if pastSlot.afterGenesis and if consensusFork < ConsensusFork.Deneb:
msgSlot + ATTESTATION_PROPAGATION_SLOT_RANGE < pastSlot.slot: # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/p2p-interface.md#configuration
return errIgnore("Attestation slot in the past") # The spec value of ATTESTATION_PROPAGATION_SLOT_RANGE is 32, but it can
# retransmit attestations on the cusp of being out of spec, and which by
# the time they reach their destination might be out of spec.
const ATTESTATION_PROPAGATION_SLOT_RANGE = 28
if msgSlot + ATTESTATION_PROPAGATION_SLOT_RANGE < pastSlot.slot:
return errIgnore("Attestation slot in the past")
else:
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_attestation_subnet_id
# "[IGNORE] the epoch of attestation.data.slot is either the current or
# previous epoch (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e.
# compute_epoch_at_slot(attestation.data.slot) in
# (get_previous_epoch(state), get_current_epoch(state))"
#
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof
# "[IGNORE] the epoch of aggregate.data.slot is either the current or
# previous epoch (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e.
# compute_epoch_at_slot(aggregate.data.slot) in
# (get_previous_epoch(state), get_current_epoch(state))"
if msgSlot.epoch < pastSlot.slot.epoch.get_previous_epoch:
return errIgnore("Attestation slot in the past")
ok(msgSlot)
func check_slot_exact(msgSlot: Slot, wallTime: BeaconTime):
Result[Slot, ValidationError] =
let futureSlot = (wallTime + MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
if not futureSlot.afterGenesis or msgSlot > futureSlot.slot:
return errIgnore("Sync committee slot in the future")
let pastSlot = (wallTime - MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
if pastSlot.afterGenesis and msgSlot < pastSlot.slot:
return errIgnore("Sync committee slot in the past")
ok(msgSlot) ok(msgSlot)
@ -120,10 +150,9 @@ func check_beacon_and_target_block(
? check_attestation_block(pool, data.slot, blck) ? check_attestation_block(pool, data.slot, blck)
# [REJECT] The attestation's target block is an ancestor of the block named # [REJECT] The attestation's target block is an ancestor of the block named
# in the LMD vote -- i.e. get_ancestor(store, # in the LMD vote -- i.e.
# attestation.data.beacon_block_root, # get_checkpoint_block(store, attestation.data.beacon_block_root,
# compute_start_slot_at_epoch(attestation.data.target.epoch)) == # attestation.data.target.epoch) == attestation.data.target.root
# attestation.data.target.root
# the sanity of target.epoch has been checked by check_attestation_slot_target # the sanity of target.epoch has been checked by check_attestation_slot_target
let target = blck.atCheckpoint(data.target).valueOr: let target = blck.atCheckpoint(data.target).valueOr:
return errReject("Attestation target is not ancestor of LMD vote block") return errReject("Attestation target is not ancestor of LMD vote block")
@ -527,7 +556,8 @@ proc validateBeaconBlock*(
ok() ok()
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof
proc validateAttestation*( proc validateAttestation*(
pool: ref AttestationPool, pool: ref AttestationPool,
batchCrypto: ref BatchCrypto, batchCrypto: ref BatchCrypto,
@ -556,8 +586,13 @@ proc validateAttestation*(
# attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot # attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot
# >= attestation.data.slot (a client MAY queue future attestations for # >= attestation.data.slot (a client MAY queue future attestations for
# processing at the appropriate slot). # processing at the appropriate slot).
#
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_attestation_subnet_id
# modifies this for Deneb and newer forks.
block: block:
let v = check_propagation_slot_range(slot, wallTime) let v = check_propagation_slot_range(
pool.dag.cfg.consensusForkAtEpoch(wallTime.slotOrZero.epoch), slot,
wallTime)
if v.isErr(): # [IGNORE] if v.isErr(): # [IGNORE]
return err(v.error()) return err(v.error())
@ -584,11 +619,10 @@ proc validateAttestation*(
# The following rule follows implicitly from that we clear out any # The following rule follows implicitly from that we clear out any
# unviable blocks from the chain dag: # unviable blocks from the chain dag:
# #
# The current finalized_checkpoint is an ancestor of the block defined by # [IGNORE] The current finalized_checkpoint is an ancestor of the block
# attestation.data.beacon_block_root -- i.e. get_ancestor(store, # defined by attestation.data.beacon_block_root -- i.e.
# attestation.data.beacon_block_root, # get_checkpoint_block(store, attestation.data.beacon_block_root,
# compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == # store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root
# store.finalized_checkpoint.root
let let
shufflingRef = shufflingRef =
pool.dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr: pool.dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr:
@ -693,7 +727,8 @@ proc validateAttestation*(
return ok((validator_index, sig)) return ok((validator_index, sig))
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof
proc validateAggregate*( proc validateAggregate*(
pool: ref AttestationPool, pool: ref AttestationPool,
batchCrypto: ref BatchCrypto, batchCrypto: ref BatchCrypto,
@ -723,8 +758,13 @@ proc validateAggregate*(
# ATTESTATION_PROPAGATION_SLOT_RANGE slots (with a # ATTESTATION_PROPAGATION_SLOT_RANGE slots (with a
# MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. aggregate.data.slot + # MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. aggregate.data.slot +
# ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= aggregate.data.slot # ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= aggregate.data.slot
#
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof
# modifies this for Deneb and newer forks.
block: block:
let v = check_propagation_slot_range(slot, wallTime) let v = check_propagation_slot_range(
pool.dag.cfg.consensusForkAtEpoch(wallTime.slotOrZero.epoch), slot,
wallTime)
if v.isErr(): # [IGNORE] if v.isErr(): # [IGNORE]
return err(v.error()) return err(v.error())
@ -883,11 +923,10 @@ proc validateAggregate*(
# The following rule follows implicitly from that we clear out any # The following rule follows implicitly from that we clear out any
# unviable blocks from the chain dag: # unviable blocks from the chain dag:
# #
# The current finalized_checkpoint is an ancestor of the block defined by # [IGNORE] The current finalized_checkpoint is an ancestor of the block
# aggregate.data.beacon_block_root -- i.e. get_ancestor(store, # defined by aggregate.data.beacon_block_root -- i.e.
# aggregate.data.beacon_block_root, # get_checkpoint_block(store, aggregate.data.beacon_block_root,
# compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == # finalized_checkpoint.epoch) == store.finalized_checkpoint.root
# store.finalized_checkpoint.root
# Only valid aggregates go in the list # Only valid aggregates go in the list
if pool.nextAttestationEpoch.lenu64 <= aggregate_and_proof.aggregator_index: if pool.nextAttestationEpoch.lenu64 <= aggregate_and_proof.aggregator_index:
@ -1040,7 +1079,7 @@ proc validateSyncCommitteeMessage*(
# [IGNORE] The message's slot is for the current slot (with a # [IGNORE] The message's slot is for the current slot (with a
# `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. # `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e.
# `sync_committee_message.slot == current_slot`. # `sync_committee_message.slot == current_slot`.
let v = check_propagation_slot_range(msg.slot, wallTime) let v = check_slot_exact(msg.slot, wallTime)
if v.isErr(): if v.isErr():
return err(v.error()) return err(v.error())
@ -1135,7 +1174,7 @@ proc validateContribution*(
# (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) # (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance)
# i.e. contribution.slot == current_slot. # i.e. contribution.slot == current_slot.
block: block:
let v = check_propagation_slot_range(syncCommitteeSlot, wallTime) let v = check_slot_exact(syncCommitteeSlot, wallTime)
if v.isErr(): # [IGNORE] if v.isErr(): # [IGNORE]
return err(v.error()) return err(v.error())