Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Export check_addresses on TransportConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
Attila Vágvölgyi committed Jan 4, 2022
1 parent 7e70452 commit f046bf1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 65 deletions.
59 changes: 57 additions & 2 deletions client/network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ use std::{
borrow::Cow,
collections::HashMap,
convert::TryFrom,
error::Error,
fs,
future::Future,
io::{self, Write},
Expand Down Expand Up @@ -605,6 +604,28 @@ impl NonDefaultSetConfig {
}
}

/// A trait that enables handling different types with a single relevant multiaddress in a generic
/// way
pub trait AsMultiAddr {
/// Extract the multiaddress from the type.
///
/// NOTE: Do not implement this trait for types where it is ambiguous which address should be
/// extracted here.
fn as_multiaddr(&self) -> &Multiaddr;
}

impl AsMultiAddr for Multiaddr {
fn as_multiaddr(&self) -> &Multiaddr {
self
}
}

impl AsMultiAddr for MultiaddrWithPeerId {
fn as_multiaddr(&self) -> &Multiaddr {
&self.multiaddr
}
}

/// Configuration for the transport layer.
#[derive(Clone, Debug)]
pub enum TransportConfig {
Expand All @@ -625,6 +646,40 @@ pub enum TransportConfig {
MemoryOnly,
}

impl TransportConfig {
/// Checks every address and gives an error if any of them do not match the specified transport
pub fn check_addresses<'a, T>(
&self,
addresses: impl IntoIterator<Item = &'a T>,
) -> Result<(), crate::error::Error>
where
T: AsMultiAddr + 'a,
{
let memory_only = matches!(self, TransportConfig::MemoryOnly);
let invalid_addresses: Vec<_> = addresses
.into_iter()
.map(|x| x.as_multiaddr())
.filter(|x| {
x.iter().any(|y| {
// MemoryOnly can only have `/memory/...` protocols, while
// Normal must not have any
memory_only != matches!(y, libp2p::core::multiaddr::Protocol::Memory(_))
})
})
.cloned()
.collect();

if invalid_addresses.is_empty() {
Ok(())
} else {
Err(crate::error::Error::AddressesForAnotherTransport {
transport: self.clone(),
addresses: invalid_addresses,
})
}
}
}

/// The policy for connections to non-reserved peers.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum NonReservedPeerMode {
Expand Down Expand Up @@ -735,7 +790,7 @@ where
P: AsRef<Path>,
F: for<'r> FnOnce(&'r mut [u8]) -> Result<K, E>,
G: FnOnce() -> K,
E: Error + Send + Sync + 'static,
E: std::error::Error + Send + Sync + 'static,
W: Fn(&K) -> Vec<u8>,
{
std::fs::read(&file)
Expand Down
74 changes: 11 additions & 63 deletions client/network/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,34 +142,17 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
/// for the network processing to advance. From it, you can extract a `NetworkService` using
/// `worker.service()`. The `NetworkService` can be shared through the codebase.
pub fn new(mut params: Params<B, H>) -> Result<Self, Error> {
// Ensure the listen addresses are consistent with the transport.
ensure_addresses_consistent_with_transport(
params.network_config.listen_addresses.iter(),
&params.network_config.transport,
)?;
ensure_addresses_consistent_with_transport(
params.network_config.boot_nodes.iter().map(|x| &x.multiaddr),
&params.network_config.transport,
)?;
ensure_addresses_consistent_with_transport(
params
.network_config
.default_peers_set
.reserved_nodes
.iter()
.map(|x| &x.multiaddr),
&params.network_config.transport,
)?;
let transport_config = &params.network_config.transport;

// Ensure all configured addresses are consistent with the transport.
transport_config.check_addresses(&params.network_config.listen_addresses)?;
transport_config.check_addresses(&params.network_config.boot_nodes)?;
transport_config
.check_addresses(&params.network_config.default_peers_set.reserved_nodes)?;
for extra_set in &params.network_config.extra_sets {
ensure_addresses_consistent_with_transport(
extra_set.set_config.reserved_nodes.iter().map(|x| &x.multiaddr),
&params.network_config.transport,
)?;
transport_config.check_addresses(&extra_set.set_config.reserved_nodes)?;
}
ensure_addresses_consistent_with_transport(
params.network_config.public_addresses.iter(),
&params.network_config.transport,
)?;
transport_config.check_addresses(&params.network_config.public_addresses)?;

let (to_worker, from_service) = tracing_unbounded("mpsc_network_worker");

Expand Down Expand Up @@ -212,8 +195,8 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
&params.network_config,
iter::once(Vec::new())
.chain(
(0..params.network_config.extra_sets.len() - 1)
.map(|_| default_notif_handshake_message.clone()),
iter::repeat(default_notif_handshake_message)
.take(params.network_config.extra_sets.len() - 1),
)
.collect(),
params.block_announce_validator,
Expand Down Expand Up @@ -2163,38 +2146,3 @@ impl<'a, B: BlockT> Link<B> for NetworkLink<'a, B> {
.request_justification(hash, number)
}
}

fn ensure_addresses_consistent_with_transport<'a>(
addresses: impl Iterator<Item = &'a Multiaddr>,
transport: &TransportConfig,
) -> Result<(), Error> {
if matches!(transport, TransportConfig::MemoryOnly) {
let addresses: Vec<_> = addresses
.filter(|x| {
x.iter().any(|y| !matches!(y, libp2p::core::multiaddr::Protocol::Memory(_)))
})
.cloned()
.collect();

if !addresses.is_empty() {
return Err(Error::AddressesForAnotherTransport {
transport: transport.clone(),
addresses,
})
}
} else {
let addresses: Vec<_> = addresses
.filter(|x| x.iter().any(|y| matches!(y, libp2p::core::multiaddr::Protocol::Memory(_))))
.cloned()
.collect();

if !addresses.is_empty() {
return Err(Error::AddressesForAnotherTransport {
transport: transport.clone(),
addresses,
})
}
}

Ok(())
}

0 comments on commit f046bf1

Please sign in to comment.