doppelganger detection walltime refactor (#2656)
* strawman doppelganger detection walltime refactor * move DoppelgangerProtection to Eth2Processor * increase comment precision * document difference between broadcastStartEpoch and nodeLaunchSlot, and allow for one-slot overlap to avoid false positives on intra-slot restarts
This commit is contained in:
parent
9d48097de0
commit
9ad8310157
|
@ -45,6 +45,18 @@ declareHistogram beacon_block_delay,
|
|||
"Time(s) between slot start and beacon block reception", buckets = delayBuckets
|
||||
|
||||
type
|
||||
DoppelgangerProtection = object
|
||||
broadcastStartEpoch*: Epoch ##\
|
||||
## Set anew, each time gossip is re-enabled after syncing completes, so
|
||||
## might reset multiple times per instance. This allows some safe level
|
||||
## of gossip interleaving between nodes so long as they don't gossip at
|
||||
## the same time.
|
||||
|
||||
nodeLaunchSlot: Slot ##\
|
||||
## Set once, at node launch. This functions as a basic protection against
|
||||
## false positives from attestations persisting within the gossip network
|
||||
## across quick restarts.
|
||||
|
||||
Eth2Processor* = object
|
||||
doppelGangerDetectionEnabled*: bool
|
||||
getWallTime*: GetWallTimeFn
|
||||
|
@ -88,6 +100,8 @@ proc new*(T: type Eth2Processor,
|
|||
getWallTime: GetWallTimeFn): ref Eth2Processor =
|
||||
(ref Eth2Processor)(
|
||||
doppelGangerDetectionEnabled: doppelGangerDetectionEnabled,
|
||||
doppelgangerDetection: DoppelgangerProtection(
|
||||
nodeLaunchSlot: getWallTime().slotOrZero),
|
||||
getWallTime: getWallTime,
|
||||
blockProcessor: blockProcessor,
|
||||
dag: dag,
|
||||
|
@ -158,15 +172,15 @@ proc blockValidator*(
|
|||
|
||||
proc checkForPotentialDoppelganger(
|
||||
self: var Eth2Processor, attestation: Attestation,
|
||||
attesterIndices: openArray[ValidatorIndex], wallSlot: Slot) =
|
||||
let epoch = wallSlot.epoch
|
||||
|
||||
# Only check for current epoch, not potential attestations bouncing around
|
||||
# from up to several minutes prior.
|
||||
if attestation.data.slot.epoch < epoch:
|
||||
attesterIndices: openArray[ValidatorIndex]) =
|
||||
# Only check for attestations after node launch. There might be one slot of
|
||||
# overlap in quick intra-slot restarts so trade off a few true negatives in
|
||||
# the service of avoiding more likely false positives.
|
||||
if attestation.data.slot <= self.doppelgangerDetection.nodeLaunchSlot + 1:
|
||||
return
|
||||
|
||||
if epoch < self.doppelgangerDetection.broadcastStartEpoch:
|
||||
if attestation.data.slot.epoch <
|
||||
self.doppelgangerDetection.broadcastStartEpoch:
|
||||
let tgtBlck = self.dag.getRef(attestation.data.target.root)
|
||||
doAssert not tgtBlck.isNil # because attestation is valid above
|
||||
|
||||
|
@ -221,8 +235,7 @@ proc attestationValidator*(
|
|||
|
||||
let (attestation_index, sig) = v.get()
|
||||
|
||||
self[].checkForPotentialDoppelganger(
|
||||
attestation, [attestation_index], wallSlot)
|
||||
self[].checkForPotentialDoppelganger(attestation, [attestation_index])
|
||||
|
||||
trace "Attestation validated"
|
||||
self.attestationPool[].addAttestation(
|
||||
|
@ -269,8 +282,7 @@ proc aggregateValidator*(
|
|||
let (attesting_indices, sig) = v.get()
|
||||
|
||||
self[].checkForPotentialDoppelganger(
|
||||
signedAggregateAndProof.message.aggregate, attesting_indices,
|
||||
wallSlot)
|
||||
signedAggregateAndProof.message.aggregate, attesting_indices)
|
||||
|
||||
trace "Aggregate validated",
|
||||
aggregator_index = signedAggregateAndProof.message.aggregator_index,
|
||||
|
|
|
@ -472,9 +472,6 @@ type
|
|||
current_justified_checkpoint*: Checkpoint
|
||||
finalized_checkpoint*: Checkpoint
|
||||
|
||||
DoppelgangerProtection* = object
|
||||
broadcastStartEpoch*: Epoch
|
||||
|
||||
type
|
||||
# Caches for computing justificiation, rewards and penalties - based on
|
||||
# implementation in Lighthouse:
|
||||
|
|
Loading…
Reference in New Issue