Skip to content

Commit 7d0aa89

Browse files
lexnvbkchr
andauthored
litep2p/discovery: Publish authority records with external addresses only (#5176)
This PR reduces the occurrences for identified observed addresses. Litep2p discovers its external addresses by inspecting the `IdentifyInfo::ObservedAddress` field reported by other peers. After we get 5 confirmations of the same external observed address (the address the peer dialed to reach us), the address is reported through the network layer. The PR effectively changes this from 5 to 2. This has a subtle implication on freshly started nodes for the authority-discovery discussed below. The PR also makes the authority discovery a bit more robust by not publishing records if the node doesn't have addresses yet to report. This aims to fix a scenario where: - the litep2p node has started, it has some pending observed addresses but less than 5 - the authorit-discovery publishes a record, but at this time the node doesn't have any addresses discovered and the record is published without addresses -> this means other nodes will not be able to reach us Next Steps - [ ] versi testing Closes: #5147 cc @paritytech/networking --------- Signed-off-by: Alexandru Vasile <[email protected]> Co-authored-by: Bastian Köcher <[email protected]>
1 parent 39daa61 commit 7d0aa89

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

substrate/client/authority-discovery/src/worker.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use ip_network::IpNetwork;
3737
use libp2p::kad::{PeerRecord, Record};
3838
use linked_hash_set::LinkedHashSet;
3939

40-
use log::{debug, error};
40+
use log::{debug, error, trace};
4141
use prometheus_endpoint::{register, Counter, CounterVec, Gauge, Opts, U64};
4242
use prost::Message;
4343
use rand::{seq::SliceRandom, thread_rng};
@@ -416,10 +416,12 @@ where
416416
})
417417
.collect::<Vec<_>>();
418418

419-
debug!(
420-
target: LOG_TARGET,
421-
"Publishing authority DHT record peer_id='{local_peer_id}' addresses='{addresses:?}'",
422-
);
419+
if !addresses.is_empty() {
420+
debug!(
421+
target: LOG_TARGET,
422+
"Publishing authority DHT record peer_id='{local_peer_id}' with addresses='{addresses:?}'",
423+
);
424+
}
423425

424426
// The address must include the local peer id.
425427
addresses
@@ -437,6 +439,17 @@ where
437439
Role::Discover => return Ok(()),
438440
};
439441

442+
let addresses = serialize_addresses(self.addresses_to_publish());
443+
if addresses.is_empty() {
444+
trace!(
445+
target: LOG_TARGET,
446+
"No addresses to publish. Skipping publication."
447+
);
448+
449+
self.publish_interval.set_to_start();
450+
return Ok(())
451+
}
452+
440453
let keys =
441454
Worker::<Client, Block, DhtEventStream>::get_own_public_keys_within_authority_set(
442455
key_store.clone(),
@@ -459,8 +472,6 @@ where
459472
self.query_interval.set_to_start();
460473
}
461474

462-
let addresses = serialize_addresses(self.addresses_to_publish());
463-
464475
if let Some(metrics) = &self.metrics {
465476
metrics.publish.inc();
466477
metrics

substrate/client/network/src/litep2p/discovery.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,18 @@ const KADEMLIA_QUERY_INTERVAL: Duration = Duration::from_secs(5);
6666
/// mDNS query interval.
6767
const MDNS_QUERY_INTERVAL: Duration = Duration::from_secs(30);
6868

69-
/// Minimum number of confirmations received before an address is verified.
70-
const MIN_ADDRESS_CONFIRMATIONS: usize = 5;
71-
72-
// The minimum number of peers we expect an answer before we terminate the request.
69+
/// The minimum number of peers we expect an answer before we terminate the request.
7370
const GET_RECORD_REDUNDANCY_FACTOR: usize = 4;
7471

72+
/// The maximum number of tracked external addresses we allow.
73+
const MAX_EXTERNAL_ADDRESSES: u32 = 32;
74+
75+
/// Minimum number of confirmations received before an address is verified.
76+
///
77+
/// Note: all addresses are confirmed by libp2p on the first encounter. This aims to make
78+
/// addresses a bit more robust.
79+
const MIN_ADDRESS_CONFIRMATIONS: usize = 2;
80+
7581
/// Discovery events.
7682
#[derive(Debug)]
7783
pub enum DiscoveryEvent {
@@ -195,7 +201,7 @@ pub struct Discovery {
195201
listen_addresses: Arc<RwLock<HashSet<Multiaddr>>>,
196202

197203
/// External address confirmations.
198-
address_confirmations: LruMap<Multiaddr, usize>,
204+
address_confirmations: LruMap<Multiaddr, HashSet<PeerId>>,
199205

200206
/// Delay to next `FIND_NODE` query.
201207
duration_to_next_find_query: Duration,
@@ -278,7 +284,7 @@ impl Discovery {
278284
find_node_query_id: None,
279285
pending_events: VecDeque::new(),
280286
duration_to_next_find_query: Duration::from_secs(1),
281-
address_confirmations: LruMap::new(ByLength::new(8)),
287+
address_confirmations: LruMap::new(ByLength::new(MAX_EXTERNAL_ADDRESSES)),
282288
allow_non_global_addresses: config.allow_non_globals_in_dht,
283289
public_addresses: config.public_addresses.iter().cloned().map(Into::into).collect(),
284290
next_kad_query: Some(Delay::new(KADEMLIA_QUERY_INTERVAL)),
@@ -428,7 +434,7 @@ impl Discovery {
428434
}
429435

430436
/// Check if `address` can be considered a new external address.
431-
fn is_new_external_address(&mut self, address: &Multiaddr) -> bool {
437+
fn is_new_external_address(&mut self, address: &Multiaddr, peer: PeerId) -> bool {
432438
log::trace!(target: LOG_TARGET, "verify new external address: {address}");
433439

434440
// is the address one of our known addresses
@@ -444,14 +450,14 @@ impl Discovery {
444450

445451
match self.address_confirmations.get(address) {
446452
Some(confirmations) => {
447-
*confirmations += 1usize;
453+
confirmations.insert(peer);
448454

449-
if *confirmations >= MIN_ADDRESS_CONFIRMATIONS {
455+
if confirmations.len() >= MIN_ADDRESS_CONFIRMATIONS {
450456
return true
451457
}
452458
},
453459
None => {
454-
self.address_confirmations.insert(address.clone(), 1usize);
460+
self.address_confirmations.insert(address.clone(), Default::default());
455461
},
456462
}
457463

@@ -563,7 +569,7 @@ impl Stream for Discovery {
563569
supported_protocols,
564570
observed_address,
565571
})) => {
566-
if this.is_new_external_address(&observed_address) {
572+
if this.is_new_external_address(&observed_address, peer) {
567573
this.pending_events.push_back(DiscoveryEvent::ExternalAddressDiscovered {
568574
address: observed_address.clone(),
569575
});

substrate/client/network/src/litep2p/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkBackend<B, H> for Litep2pNetworkBac
920920
let mut addresses = self.external_addresses.write();
921921

922922
if addresses.insert(address.clone()) {
923-
log::info!(target: LOG_TARGET, "discovered new external address for our node: {address}");
923+
log::info!(target: LOG_TARGET, "🔍 Discovered new external address for our node: {address}");
924924
}
925925
}
926926
Some(DiscoveryEvent::Ping { peer, rtt }) => {

0 commit comments

Comments
 (0)