From 273f31b7aa3069bd62cb80c340f9d1912baf67a5 Mon Sep 17 00:00:00 2001 From: Roman Borschel <romanb@users.noreply.github.com> Date: Wed, 10 Jun 2020 18:50:37 +0200 Subject: [PATCH] Avoid self-lookups in Authority Discovery (#6317) * Ensure authority discovery avoids self-lookups. Thereby additionally guard the `NetworkService` against adding the local peer to the PSM or registering a "known address" for the local peer. * Clarify comments. * See if returning errors is ok. --- .../client/authority-discovery/src/lib.rs | 23 ++++++++++++---- substrate/client/network/src/service.rs | 27 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/substrate/client/authority-discovery/src/lib.rs b/substrate/client/authority-discovery/src/lib.rs index bc76c143314..de98e6a4a38 100644 --- a/substrate/client/authority-discovery/src/lib.rs +++ b/substrate/client/authority-discovery/src/lib.rs @@ -294,13 +294,26 @@ where .authorities(&id) .map_err(Error::CallingRuntime)?; + let local_keys = match &self.role { + Role::Authority(key_store) => { + key_store.read() + .sr25519_public_keys(key_types::AUTHORITY_DISCOVERY) + .into_iter() + .collect::<HashSet<_>>() + }, + Role::Sentry => HashSet::new(), + }; + for authority_id in authorities.iter() { - if let Some(metrics) = &self.metrics { - metrics.request.inc(); - } + // Make sure we don't look up our own keys. + if !local_keys.contains(authority_id.as_ref()) { + if let Some(metrics) = &self.metrics { + metrics.request.inc(); + } - self.network - .get_value(&hash_authority_id(authority_id.as_ref())); + self.network + .get_value(&hash_authority_id(authority_id.as_ref())); + } } Ok(()) diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index fd58aa631d6..2297fe6a52f 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -672,8 +672,15 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkService<B, H> { /// Adds a `PeerId` and its address as reserved. The string should encode the address /// and peer ID of the remote node. + /// + /// Returns an `Err` if the given string is not a valid multiaddress + /// or contains an invalid peer ID (which includes the local peer ID). pub fn add_reserved_peer(&self, peer: String) -> Result<(), String> { let (peer_id, addr) = parse_str_addr(&peer).map_err(|e| format!("{:?}", e))?; + // Make sure the local peer ID is never added to the PSM. + if peer_id == self.local_peer_id { + return Err("Local peer ID cannot be added as a reserved peer.".to_string()) + } self.peerset.add_reserved_peer(peer_id.clone()); let _ = self .to_worker @@ -694,12 +701,26 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkService<B, H> { } /// Modify a peerset priority group. + /// + /// Returns an `Err` if one of the given addresses contains an invalid + /// peer ID (which includes the local peer ID). pub fn set_priority_group(&self, group_id: String, peers: HashSet<Multiaddr>) -> Result<(), String> { - let peers = peers.into_iter().map(|p| { - parse_addr(p).map_err(|e| format!("{:?}", e)) - }).collect::<Result<Vec<(PeerId, Multiaddr)>, String>>()?; + let peers = peers.into_iter() + .map(|p| match parse_addr(p) { + Err(e) => Err(format!("{:?}", e)), + Ok((peer, addr)) => + // Make sure the local peer ID is never added to the PSM + // or added as a "known address", even if given. + if peer == self.local_peer_id { + Err("Local peer ID in priority group.".to_string()) + } else { + Ok((peer, addr)) + } + }) + .collect::<Result<Vec<(PeerId, Multiaddr)>, String>>()?; let peer_ids = peers.iter().map(|(peer_id, _addr)| peer_id.clone()).collect(); + self.peerset.set_priority_group(group_id, peer_ids); for (peer_id, addr) in peers.into_iter() { -- GitLab