diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 1162f63de0a..6d962993b58 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -56,6 +56,7 @@ use lighthouse_network::rpc::RPCError; use lighthouse_network::types::{NetworkGlobals, SyncState}; use lighthouse_network::SyncInfo; use lighthouse_network::{PeerAction, PeerId}; +use lru_cache::LRUTimeCache; use slog::{crit, debug, error, info, o, trace, warn, Logger}; use std::ops::Sub; use std::sync::Arc; @@ -72,6 +73,11 @@ use types::{BlobSidecar, EthSpec, Hash256, SignedBeaconBlock, Slot}; /// blocks for. pub const SLOT_IMPORT_TOLERANCE: usize = 32; +/// Suppress duplicated `UnknownBlockHashFromAttestation` events for some duration of time. In +/// practice peers are likely to send the same root during a single slot. 30 seconds is a rather +/// arbitrary number that covers a full slot, but allows recovery if sync get stuck for a few slots. +const NOTIFIED_UNKNOWN_ROOT_EXPIRY_SECONDS: u64 = 30; + pub type Id = u32; #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] @@ -199,6 +205,10 @@ pub struct SyncManager { backfill_sync: BackFillSync, block_lookups: BlockLookups, + /// debounce duplicated `UnknownBlockHashFromAttestation` for the same root peer tuple. A peer + /// may forward us thousands of a attestations, each one triggering an individual event. Only + /// one event is useful, the rest generating log noise and wasted cycles + notified_unknown_roots: LRUTimeCache<(PeerId, Hash256)>, /// The logger for the import manager. log: Logger, @@ -262,6 +272,9 @@ impl SyncManager { log.new(o!("service" => "backfill_sync")), ), block_lookups: BlockLookups::new(log.new(o!("service"=> "lookup_sync"))), + notified_unknown_roots: LRUTimeCache::new(Duration::from_secs( + NOTIFIED_UNKNOWN_ROOT_EXPIRY_SECONDS, + )), log: log.clone(), } } @@ -622,7 +635,11 @@ impl SyncManager { ); } SyncMessage::UnknownBlockHashFromAttestation(peer_id, block_root) => { - self.handle_unknown_block_root(peer_id, block_root); + if !self.notified_unknown_roots.contains(&(peer_id, block_root)) { + self.notified_unknown_roots.insert((peer_id, block_root)); + debug!(self.log, "Received unknown block hash message"; "block_root" => ?block_root, "peer" => ?peer_id); + self.handle_unknown_block_root(peer_id, block_root); + } } SyncMessage::Disconnect(peer_id) => { debug!(self.log, "Received disconnected message"; "peer_id" => %peer_id);