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()
|
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())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue