Skip to content

Commit

Permalink
docs: more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Oct 24, 2022
1 parent abffb85 commit 816df87
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 15 deletions.
9 changes: 9 additions & 0 deletions crates/net/discv4/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub struct Discv4Config {
pub ping_interval: Duration,
/// The duration of we consider a ping timed out.
pub ping_timeout: Duration,
/// The rate at which lookups should be triggered.
pub lookup_interval: Duration,
/// The duration of we consider a FindNode request timed out.
pub find_node_timeout: Duration,
/// The duration we set for neighbours responses
Expand Down Expand Up @@ -49,6 +51,7 @@ impl Default for Discv4Config {
ping_timeout: Duration::from_secs(5),
find_node_timeout: Duration::from_secs(2),
neighbours_timeout: Duration::from_secs(30),
lookup_interval: Duration::from_secs(20),
permit_ban_list: PermitBanList::default(),
ban_duration: Some(Duration::from_secs(3600)), // 1 hour
bootstrap_nodes: Default::default(),
Expand Down Expand Up @@ -93,6 +96,12 @@ impl Discv4ConfigBuilder {
self
}

/// Sets the lookup interval duration.
pub fn lookup_interval(&mut self, lookup_interval: Duration) -> &mut Self {
self.config.lookup_interval = lookup_interval;
self
}

/// Set the default duration for which nodes are banned for. This timeouts are checked every 5
/// minutes, so the precision will be to the nearest 5 minutes. If set to `None`, bans from
/// the filter will last indefinitely. Default is 1 hour.
Expand Down
52 changes: 37 additions & 15 deletions crates/net/discv4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,12 @@ pub struct Discv4Service {
/// Sender for sending outgoing messages
egress: EgressSender,
/// Buffered pending pings to apply backpressure.
adding_nodes: VecDeque<(NodeRecord, PingReason)>,
///
/// Lookups behave like bursts of requests: Endpoint proof followed by `FindNode` request. [Recursive lookups](https://github.com/ethereum/devp2p/blob/master/discv4.md#recursive-lookup) can trigger multiple followup Pings+FindNode requests.
/// A cap on concurrent `Ping` prevents escalation where: A large number of new nodes
/// discovered via `FindNode` in a recursive lookup triggers a large number of `Ping`s, and
/// followup `FindNode` requests.... Buffering them effectively prevents high `Ping` peaks.
queued_pings: VecDeque<(NodeRecord, PingReason)>,
/// Currently active pings to specific nodes.
pending_pings: HashMap<NodeId, PingRequest>,
/// Currently active FindNode requests
Expand All @@ -224,16 +229,16 @@ pub struct Discv4Service {
commands_rx: Option<mpsc::Receiver<Discv4Command>>,
/// All subscribers for table updates
update_listeners: Vec<mpsc::Sender<TableUpdate>>,
/// The interval when to trigger self lookup
self_lookup_interval: Interval,
/// The interval when to trigger lookups
lookup_interval: Interval,
/// Used to rotate targets to lookup
lookup_rotator: LookupRotator,
/// Interval when to recheck active requests
evict_expired_requests_interval: Interval,
/// Interval when to resend pings.
ping_interval: Interval,
/// How this services is configured
config: Discv4Config,
/// Used to rotate targets to lookup
lookup_rotator: LookupRotator,
}

impl Discv4Service {
Expand Down Expand Up @@ -269,7 +274,7 @@ impl Discv4Service {
// entries first
let self_lookup_interval = tokio::time::interval_at(
tokio::time::Instant::now() + config.ping_timeout / 2,
LOOKUP_INTERVAL,
config.lookup_interval,
);

let ping_interval = tokio::time::interval(config.ping_interval);
Expand All @@ -287,14 +292,14 @@ impl Discv4Service {
tasks,
ingress: ingress_rx,
egress: egress_tx,
adding_nodes: Default::default(),
queued_pings: Default::default(),
pending_pings: Default::default(),
pending_find_nodes: Default::default(),
check_timestamps: false,
bootstrap_node_ids,
commands_rx,
update_listeners: Vec::with_capacity(1),
self_lookup_interval,
lookup_interval: self_lookup_interval,
ping_interval,
evict_expired_requests_interval,
config,
Expand All @@ -307,9 +312,15 @@ impl Discv4Service {
self.local_address
}

/// This will bootstrap lookups by connecting to the configured boot nodes.
/// Bootstraps the local node to join the DHT.
///
/// This is equivalent to adding all bootnodes via
/// Bootstrapping is a multi-step operation that starts with a lookup of the local node's
/// own ID in the DHT. This introduces the local node to the other nodes
/// in the DHT and populates its routing table with the closest proven neighbours.
///
/// This is equivalent to adding all bootnodes via [`Self::add_node()`].
///
/// **Note:** This is a noop if there are no bootnodes.
pub fn bootstrap(&mut self) {
for node in self.config.bootstrap_nodes.clone() {
debug!(?node, target = "net::disc", "Adding bootstrap node");
Expand Down Expand Up @@ -357,6 +368,7 @@ impl Discv4Service {
let key = kad_key(target);

let ctx = if target == self.local_enr.id {
// TODO(mattsse): The discv5 currently does not support local key lookups: https://github.com/sigp/discv5/pull/142
LookupContext::with_listener(
target,
self.config
Expand Down Expand Up @@ -498,14 +510,14 @@ impl Discv4Service {
return
}

if self.adding_nodes.iter().any(|(n, _)| n.id == node.id) {
if self.queued_pings.iter().any(|(n, _)| n.id == node.id) {
return
}

if self.pending_pings.len() < MAX_NODES_PING {
self.send_ping(node, reason)
} else {
self.adding_nodes.push_back((node, reason))
self.queued_pings.push_back((node, reason))
}
}

Expand Down Expand Up @@ -741,7 +753,7 @@ impl Discv4Service {
/// Pops buffered ping requests and sends them.
fn ping_buffered(&mut self) {
while self.pending_pings.len() < MAX_NODES_PING {
match self.adding_nodes.pop_front() {
match self.queued_pings.pop_front() {
Some((next, reason)) => self.try_ping(next, reason),
None => break,
}
Expand Down Expand Up @@ -769,7 +781,7 @@ impl Discv4Service {
/// if it has sent a valid Pong response with matching ping hash within the last 12 hours.
pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll<()> {
// trigger self lookup
if self.self_lookup_interval.poll_tick(cx).is_ready() {
if self.lookup_interval.poll_tick(cx).is_ready() {
let target = self.lookup_rotator.next(&self.local_enr.id);
self.lookup_with(target, None);
}
Expand Down Expand Up @@ -1195,8 +1207,18 @@ mod tests {

let _handle = service.spawn();

let mut table = HashMap::new();
while let Some(update) = updates.next().await {
dbg!(update);
match update {
TableUpdate::Added(record) => {
table.insert(record.id, record);
}
TableUpdate::Removed(id) => {
table.remove(&id);
}
TableUpdate::Batch(_) => {}
}
dbg!(table.len());
}
}
}

0 comments on commit 816df87

Please sign in to comment.