update gossip validation for v1.4.0-beta.0 (#5133)
Co-authored-by: Etan Kissling <etan@status.im>
This commit is contained in:
parent
7b0e3b1c04
commit
dc5687093f
|
@ -82,25 +82,55 @@ func check_attestation_block(
|
|||
ok()
|
||||
|
||||
func check_propagation_slot_range(
|
||||
msgSlot: Slot, wallTime: BeaconTime): Result[Slot, ValidationError] =
|
||||
let
|
||||
futureSlot = (wallTime + MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
|
||||
consensusFork: ConsensusFork, 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("Attestation slot in the future")
|
||||
|
||||
let
|
||||
pastSlot = (wallTime - MAXIMUM_GOSSIP_CLOCK_DISPARITY).toSlot()
|
||||
let 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:
|
||||
return ok(msgSlot)
|
||||
|
||||
if consensusFork < ConsensusFork.Deneb:
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/p2p-interface.md#configuration
|
||||
# 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 pastSlot.afterGenesis and
|
||||
msgSlot + ATTESTATION_PROPAGATION_SLOT_RANGE < pastSlot.slot:
|
||||
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)
|
||||
|
||||
|
@ -120,10 +150,9 @@ func check_beacon_and_target_block(
|
|||
? check_attestation_block(pool, data.slot, blck)
|
||||
|
||||
# [REJECT] The attestation's target block is an ancestor of the block named
|
||||
# in the LMD vote -- i.e. get_ancestor(store,
|
||||
# attestation.data.beacon_block_root,
|
||||
# compute_start_slot_at_epoch(attestation.data.target.epoch)) ==
|
||||
# attestation.data.target.root
|
||||
# in the LMD vote -- i.e.
|
||||
# get_checkpoint_block(store, attestation.data.beacon_block_root,
|
||||
# attestation.data.target.epoch) == attestation.data.target.root
|
||||
# the sanity of target.epoch has been checked by check_attestation_slot_target
|
||||
let target = blck.atCheckpoint(data.target).valueOr:
|
||||
return errReject("Attestation target is not ancestor of LMD vote block")
|
||||
|
@ -527,7 +556,8 @@ proc validateBeaconBlock*(
|
|||
|
||||
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*(
|
||||
pool: ref AttestationPool,
|
||||
batchCrypto: ref BatchCrypto,
|
||||
|
@ -556,8 +586,13 @@ proc validateAttestation*(
|
|||
# attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot
|
||||
# >= attestation.data.slot (a client MAY queue future attestations for
|
||||
# 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:
|
||||
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]
|
||||
return err(v.error())
|
||||
|
||||
|
@ -584,11 +619,10 @@ proc validateAttestation*(
|
|||
# The following rule follows implicitly from that we clear out any
|
||||
# unviable blocks from the chain dag:
|
||||
#
|
||||
# The current finalized_checkpoint is an ancestor of the block defined by
|
||||
# attestation.data.beacon_block_root -- i.e. get_ancestor(store,
|
||||
# attestation.data.beacon_block_root,
|
||||
# compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) ==
|
||||
# store.finalized_checkpoint.root
|
||||
# [IGNORE] The current finalized_checkpoint is an ancestor of the block
|
||||
# defined by attestation.data.beacon_block_root -- i.e.
|
||||
# get_checkpoint_block(store, attestation.data.beacon_block_root,
|
||||
# store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root
|
||||
let
|
||||
shufflingRef =
|
||||
pool.dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr:
|
||||
|
@ -693,7 +727,8 @@ proc validateAttestation*(
|
|||
|
||||
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*(
|
||||
pool: ref AttestationPool,
|
||||
batchCrypto: ref BatchCrypto,
|
||||
|
@ -723,8 +758,13 @@ proc validateAggregate*(
|
|||
# ATTESTATION_PROPAGATION_SLOT_RANGE slots (with a
|
||||
# MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. 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:
|
||||
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]
|
||||
return err(v.error())
|
||||
|
||||
|
@ -883,11 +923,10 @@ proc validateAggregate*(
|
|||
# The following rule follows implicitly from that we clear out any
|
||||
# unviable blocks from the chain dag:
|
||||
#
|
||||
# The current finalized_checkpoint is an ancestor of the block defined by
|
||||
# aggregate.data.beacon_block_root -- i.e. get_ancestor(store,
|
||||
# aggregate.data.beacon_block_root,
|
||||
# compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) ==
|
||||
# store.finalized_checkpoint.root
|
||||
# [IGNORE] The current finalized_checkpoint is an ancestor of the block
|
||||
# defined by aggregate.data.beacon_block_root -- i.e.
|
||||
# get_checkpoint_block(store, aggregate.data.beacon_block_root,
|
||||
# finalized_checkpoint.epoch) == store.finalized_checkpoint.root
|
||||
|
||||
# Only valid aggregates go in the list
|
||||
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
|
||||
# `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e.
|
||||
# `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():
|
||||
return err(v.error())
|
||||
|
||||
|
@ -1135,7 +1174,7 @@ proc validateContribution*(
|
|||
# (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance)
|
||||
# i.e. contribution.slot == current_slot.
|
||||
block:
|
||||
let v = check_propagation_slot_range(syncCommitteeSlot, wallTime)
|
||||
let v = check_slot_exact(syncCommitteeSlot, wallTime)
|
||||
if v.isErr(): # [IGNORE]
|
||||
return err(v.error())
|
||||
|
||||
|
|
Loading…
Reference in New Issue