diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 94927b5edf921..b6fda5ab079cd 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -29,7 +29,7 @@ use crate::{ behaviour::{self, Behaviour, BehaviourOut}, - config::{FullNetworkConfiguration, MultiaddrWithPeerId, Params, TransportConfig}, + config::{parse_addr, FullNetworkConfiguration, MultiaddrWithPeerId, Params, TransportConfig}, discovery::DiscoveryConfig, error::Error, event::{DhtEvent, Event}, @@ -271,11 +271,14 @@ where )?; // List of multiaddresses that we know in the network. - let mut boot_node_ids = HashSet::new(); + let mut boot_node_ids = HashMap::>::new(); // Process the bootnodes. for bootnode in network_config.boot_nodes.iter() { - boot_node_ids.insert(bootnode.peer_id); + boot_node_ids + .entry(bootnode.peer_id) + .or_default() + .push(bootnode.multiaddr.clone()); known_addresses.push((bootnode.peer_id, bootnode.multiaddr.clone())); } @@ -450,6 +453,7 @@ where peers_notifications_sinks, metrics, boot_node_ids, + reported_invalid_boot_nodes: Default::default(), _marker: Default::default(), _block: Default::default(), }) @@ -1144,8 +1148,10 @@ where event_streams: out_events::OutChannels, /// Prometheus network metrics. metrics: Option, - /// The `PeerId`'s of all boot nodes. - boot_node_ids: Arc>, + /// The `PeerId`'s of all boot nodes mapped to the registered addresses. + boot_node_ids: Arc>>, + /// Boot nodes that we already have reported as invalid. + reported_invalid_boot_nodes: HashSet, /// For each peer and protocol combination, an object that allows sending notifications to /// that peer. Shared with the [`NetworkService`]. peers_notifications_sinks: Arc>>, @@ -1603,15 +1609,27 @@ where peer_id, error, ); - if self.boot_node_ids.contains(&peer_id) { + let not_reported = !self.reported_invalid_boot_nodes.contains(&peer_id); + + if let Some(addresses) = + not_reported.then(|| self.boot_node_ids.get(&peer_id)).flatten() + { if let DialError::WrongPeerId { obtained, endpoint } = &error { if let ConnectedPoint::Dialer { address, role_override: _ } = endpoint { - warn!( - "💔 The bootnode you want to connect to at `{}` provided a different peer ID `{}` than the one you expect `{}`.", - address, - obtained, - peer_id, - ); + let address_without_peer_id = parse_addr(address.clone()) + .map_or_else(|_| address.clone(), |r| r.1); + + // Only report for address of boot node that was added at startup of + // the node and not for any address that the node learned of the + // boot node. + if addresses.iter().any(|a| address_without_peer_id == *a) { + warn!( + "💔 The bootnode you want to connect to at `{address}` provided a \ + different peer ID `{obtained}` than the one you expect `{peer_id}`.", + ); + + self.reported_invalid_boot_nodes.insert(peer_id); + } } } }