mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 18:21:45 +00:00
Merge branch 'unstable' into eip4844
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::listen_addr::{ListenAddr, ListenAddress};
|
||||
use crate::rpc::config::OutboundRateLimiterConfig;
|
||||
use crate::types::GossipKind;
|
||||
use crate::{Enr, PeerIdSerialized};
|
||||
@@ -12,6 +13,7 @@ use libp2p::gossipsub::{
|
||||
use libp2p::Multiaddr;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -57,24 +59,24 @@ pub struct Config {
|
||||
/// Data directory where node's keyfile is stored
|
||||
pub network_dir: PathBuf,
|
||||
|
||||
/// IP address to listen on.
|
||||
pub listen_address: std::net::IpAddr,
|
||||
|
||||
/// The TCP port that libp2p listens on.
|
||||
pub libp2p_port: u16,
|
||||
|
||||
/// UDP port that discovery listens on.
|
||||
pub discovery_port: u16,
|
||||
/// IP addresses to listen on.
|
||||
listen_addresses: ListenAddress,
|
||||
|
||||
/// The address to broadcast to peers about which address we are listening on. None indicates
|
||||
/// that no discovery address has been set in the CLI args.
|
||||
pub enr_address: Option<std::net::IpAddr>,
|
||||
pub enr_address: (Option<Ipv4Addr>, Option<Ipv6Addr>),
|
||||
|
||||
/// The udp port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp_port: Option<u16>,
|
||||
/// The udp4 port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp4_port: Option<u16>,
|
||||
|
||||
/// The tcp port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp_port: Option<u16>,
|
||||
/// The tcp4 port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp4_port: Option<u16>,
|
||||
|
||||
/// The udp6 port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp6_port: Option<u16>,
|
||||
|
||||
/// The tcp6 port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp6_port: Option<u16>,
|
||||
|
||||
/// Target number of connected peers.
|
||||
pub target_peers: usize,
|
||||
@@ -139,6 +141,105 @@ pub struct Config {
|
||||
pub outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Sets the listening address to use an ipv4 address. The discv5 ip_mode and table filter are
|
||||
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||
/// reachable.
|
||||
pub fn set_ipv4_listening_address(&mut self, addr: Ipv4Addr, tcp_port: u16, udp_port: u16) {
|
||||
self.listen_addresses = ListenAddress::V4(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
});
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip4;
|
||||
self.discv5_config.table_filter = |enr| enr.ip4().as_ref().map_or(false, is_global_ipv4)
|
||||
}
|
||||
|
||||
/// Sets the listening address to use an ipv6 address. The discv5 ip_mode and table filter is
|
||||
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||
/// reachable.
|
||||
pub fn set_ipv6_listening_address(&mut self, addr: Ipv6Addr, tcp_port: u16, udp_port: u16) {
|
||||
self.listen_addresses = ListenAddress::V6(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
});
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||
enable_mapped_addresses: false,
|
||||
};
|
||||
self.discv5_config.table_filter = |enr| enr.ip6().as_ref().map_or(false, is_global_ipv6)
|
||||
}
|
||||
|
||||
/// Sets the listening address to use both an ipv4 and ipv6 address. The discv5 ip_mode and
|
||||
/// table filter is adjusted accordingly to ensure addresses that are present in the enr are
|
||||
/// globally reachable.
|
||||
pub fn set_ipv4_ipv6_listening_addresses(
|
||||
&mut self,
|
||||
v4_addr: Ipv4Addr,
|
||||
tcp4_port: u16,
|
||||
udp4_port: u16,
|
||||
v6_addr: Ipv6Addr,
|
||||
tcp6_port: u16,
|
||||
udp6_port: u16,
|
||||
) {
|
||||
self.listen_addresses = ListenAddress::DualStack(
|
||||
ListenAddr {
|
||||
addr: v4_addr,
|
||||
udp_port: udp4_port,
|
||||
tcp_port: tcp4_port,
|
||||
},
|
||||
ListenAddr {
|
||||
addr: v6_addr,
|
||||
udp_port: udp6_port,
|
||||
tcp_port: tcp6_port,
|
||||
},
|
||||
);
|
||||
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||
enable_mapped_addresses: true,
|
||||
};
|
||||
self.discv5_config.table_filter = |enr| match (&enr.ip4(), &enr.ip6()) {
|
||||
(None, None) => false,
|
||||
(None, Some(ip6)) => is_global_ipv6(ip6),
|
||||
(Some(ip4), None) => is_global_ipv4(ip4),
|
||||
(Some(ip4), Some(ip6)) => is_global_ipv4(ip4) && is_global_ipv6(ip6),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_listening_addr(&mut self, listen_addr: ListenAddress) {
|
||||
match listen_addr {
|
||||
ListenAddress::V4(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
}) => self.set_ipv4_listening_address(addr, tcp_port, udp_port),
|
||||
ListenAddress::V6(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
}) => self.set_ipv6_listening_address(addr, tcp_port, udp_port),
|
||||
ListenAddress::DualStack(
|
||||
ListenAddr {
|
||||
addr: ip4addr,
|
||||
udp_port: udp4_port,
|
||||
tcp_port: tcp4_port,
|
||||
},
|
||||
ListenAddr {
|
||||
addr: ip6addr,
|
||||
udp_port: udp6_port,
|
||||
tcp_port: tcp6_port,
|
||||
},
|
||||
) => self.set_ipv4_ipv6_listening_addresses(
|
||||
ip4addr, tcp4_port, udp4_port, ip6addr, tcp6_port, udp6_port,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn listen_addrs(&self) -> &ListenAddress {
|
||||
&self.listen_addresses
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
/// Generate a default network configuration.
|
||||
fn default() -> Self {
|
||||
@@ -183,7 +284,7 @@ impl Default for Config {
|
||||
.filter_rate_limiter(filter_rate_limiter)
|
||||
.filter_max_bans_per_ip(Some(5))
|
||||
.filter_max_nodes_per_ip(Some(10))
|
||||
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global(&ip))) // Filter non-global IPs
|
||||
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global_ipv4(&ip))) // Filter non-global IPs
|
||||
.ban_duration(Some(Duration::from_secs(3600)))
|
||||
.ping_interval(Duration::from_secs(300))
|
||||
.build();
|
||||
@@ -191,12 +292,16 @@ impl Default for Config {
|
||||
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
||||
Config {
|
||||
network_dir,
|
||||
listen_address: "0.0.0.0".parse().expect("valid ip address"),
|
||||
libp2p_port: 9000,
|
||||
discovery_port: 9000,
|
||||
enr_address: None,
|
||||
enr_udp_port: None,
|
||||
enr_tcp_port: None,
|
||||
listen_addresses: ListenAddress::V4(ListenAddr {
|
||||
addr: Ipv4Addr::UNSPECIFIED,
|
||||
udp_port: 9000,
|
||||
tcp_port: 9000,
|
||||
}),
|
||||
enr_address: (None, None),
|
||||
enr_udp4_port: None,
|
||||
enr_tcp4_port: None,
|
||||
enr_udp6_port: None,
|
||||
enr_tcp6_port: None,
|
||||
target_peers: 50,
|
||||
gs_config,
|
||||
discv5_config,
|
||||
@@ -363,7 +468,7 @@ pub fn gossipsub_config(network_load: u8, fork_context: Arc<ForkContext>) -> Gos
|
||||
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
|
||||
/// function is not yet stable on IpAddr.
|
||||
#[allow(clippy::nonminimal_bool)]
|
||||
fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
||||
fn is_global_ipv4(addr: &Ipv4Addr) -> bool {
|
||||
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
|
||||
// globally routable addresses in the 192.0.0.0/24 range.
|
||||
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
||||
@@ -384,3 +489,60 @@ fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
||||
// Make sure the address is not in 0.0.0.0/8
|
||||
&& addr.octets()[0] != 0
|
||||
}
|
||||
|
||||
/// NOTE: Docs taken from https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_global
|
||||
///
|
||||
/// Returns true if the address appears to be globally reachable as specified by the IANA IPv6
|
||||
/// Special-Purpose Address Registry. Whether or not an address is practically reachable will
|
||||
/// depend on your network configuration.
|
||||
///
|
||||
/// Most IPv6 addresses are globally reachable; unless they are specifically defined as not
|
||||
/// globally reachable.
|
||||
///
|
||||
/// Non-exhaustive list of notable addresses that are not globally reachable:
|
||||
///
|
||||
/// - The unspecified address (is_unspecified)
|
||||
/// - The loopback address (is_loopback)
|
||||
/// - IPv4-mapped addresses
|
||||
/// - Addresses reserved for benchmarking
|
||||
/// - Addresses reserved for documentation (is_documentation)
|
||||
/// - Unique local addresses (is_unique_local)
|
||||
/// - Unicast addresses with link-local scope (is_unicast_link_local)
|
||||
// TODO: replace with [`Ipv6Addr::is_global`] once
|
||||
// [Ip](https://github.com/rust-lang/rust/issues/27709) is stable.
|
||||
pub const fn is_global_ipv6(addr: &Ipv6Addr) -> bool {
|
||||
const fn is_documentation(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] == 0x2001) && (addr.segments()[1] == 0xdb8)
|
||||
}
|
||||
const fn is_unique_local(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] & 0xfe00) == 0xfc00
|
||||
}
|
||||
const fn is_unicast_link_local(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] & 0xffc0) == 0xfe80
|
||||
}
|
||||
!(addr.is_unspecified()
|
||||
|| addr.is_loopback()
|
||||
// IPv4-mapped Address (`::ffff:0:0/96`)
|
||||
|| matches!(addr.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
|
||||
// IPv4-IPv6 Translat. (`64:ff9b:1::/48`)
|
||||
|| matches!(addr.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
|
||||
// Discard-Only Address Block (`100::/64`)
|
||||
|| matches!(addr.segments(), [0x100, 0, 0, 0, _, _, _, _])
|
||||
// IETF Protocol Assignments (`2001::/23`)
|
||||
|| (matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
|
||||
&& !(
|
||||
// Port Control Protocol Anycast (`2001:1::1`)
|
||||
u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
|
||||
// Traversal Using Relays around NAT Anycast (`2001:1::2`)
|
||||
|| u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
|
||||
// AMT (`2001:3::/32`)
|
||||
|| matches!(addr.segments(), [0x2001, 3, _, _, _, _, _, _])
|
||||
// AS112-v6 (`2001:4:112::/48`)
|
||||
|| matches!(addr.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
|
||||
// ORCHIDv2 (`2001:20::/28`)
|
||||
|| matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
|
||||
))
|
||||
|| is_documentation(addr)
|
||||
|| is_unique_local(addr)
|
||||
|| is_unicast_link_local(addr))
|
||||
}
|
||||
|
||||
@@ -145,16 +145,39 @@ pub fn create_enr_builder_from_config<T: EnrKey>(
|
||||
enable_tcp: bool,
|
||||
) -> EnrBuilder<T> {
|
||||
let mut builder = EnrBuilder::new("v4");
|
||||
if let Some(enr_address) = config.enr_address {
|
||||
builder.ip(enr_address);
|
||||
let (maybe_ipv4_address, maybe_ipv6_address) = &config.enr_address;
|
||||
|
||||
if let Some(ip) = maybe_ipv4_address {
|
||||
builder.ip4(*ip);
|
||||
}
|
||||
if let Some(udp_port) = config.enr_udp_port {
|
||||
builder.udp4(udp_port);
|
||||
|
||||
if let Some(ip) = maybe_ipv6_address {
|
||||
builder.ip6(*ip);
|
||||
}
|
||||
// we always give it our listening tcp port
|
||||
|
||||
if let Some(udp4_port) = config.enr_udp4_port {
|
||||
builder.udp4(udp4_port);
|
||||
}
|
||||
|
||||
if let Some(udp6_port) = config.enr_udp6_port {
|
||||
builder.udp6(udp6_port);
|
||||
}
|
||||
|
||||
if enable_tcp {
|
||||
let tcp_port = config.enr_tcp_port.unwrap_or(config.libp2p_port);
|
||||
builder.tcp4(tcp_port);
|
||||
// If the ENR port is not set, and we are listening over that ip version, use the listening port instead.
|
||||
let tcp4_port = config
|
||||
.enr_tcp4_port
|
||||
.or_else(|| config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port));
|
||||
if let Some(tcp4_port) = tcp4_port {
|
||||
builder.tcp4(tcp4_port);
|
||||
}
|
||||
|
||||
let tcp6_port = config
|
||||
.enr_tcp6_port
|
||||
.or_else(|| config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port));
|
||||
if let Some(tcp6_port) = tcp6_port {
|
||||
builder.tcp6(tcp6_port);
|
||||
}
|
||||
}
|
||||
builder
|
||||
}
|
||||
|
||||
@@ -201,8 +201,13 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
||||
info!(log, "ENR Initialised"; "enr" => local_enr.to_base64(), "seq" => local_enr.seq(), "id"=> %local_enr.node_id(),
|
||||
"ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp6()
|
||||
);
|
||||
|
||||
let listen_socket = SocketAddr::new(config.listen_address, config.discovery_port);
|
||||
let listen_socket = match config.listen_addrs() {
|
||||
crate::listen_addr::ListenAddress::V4(v4_addr) => v4_addr.udp_socket_addr(),
|
||||
crate::listen_addr::ListenAddress::V6(v6_addr) => v6_addr.udp_socket_addr(),
|
||||
crate::listen_addr::ListenAddress::DualStack(_v4_addr, v6_addr) => {
|
||||
v6_addr.udp_socket_addr()
|
||||
}
|
||||
};
|
||||
|
||||
// convert the keypair into an ENR key
|
||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
||||
@@ -1015,14 +1020,27 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
|
||||
*self.network_globals.local_enr.write() = enr;
|
||||
// A new UDP socket has been detected.
|
||||
// Build a multiaddr to report to libp2p
|
||||
let mut address = Multiaddr::from(socket_addr.ip());
|
||||
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
||||
// should handle this.
|
||||
address.push(Protocol::Tcp(self.network_globals.listen_port_tcp()));
|
||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||
address,
|
||||
score: AddressScore::Finite(1),
|
||||
});
|
||||
let addr = match socket_addr.ip() {
|
||||
IpAddr::V4(v4_addr) => {
|
||||
self.network_globals.listen_port_tcp4().map(|tcp4_port| {
|
||||
Multiaddr::from(v4_addr).with(Protocol::Tcp(tcp4_port))
|
||||
})
|
||||
}
|
||||
IpAddr::V6(v6_addr) => {
|
||||
self.network_globals.listen_port_tcp6().map(|tcp6_port| {
|
||||
Multiaddr::from(v6_addr).with(Protocol::Tcp(tcp6_port))
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(address) = addr {
|
||||
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
||||
// should handle this.
|
||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||
address,
|
||||
score: AddressScore::Finite(1),
|
||||
});
|
||||
}
|
||||
}
|
||||
Discv5Event::EnrAdded { .. }
|
||||
| Discv5Event::TalkRequest(_)
|
||||
@@ -1087,7 +1105,6 @@ mod tests {
|
||||
use enr::EnrBuilder;
|
||||
use slog::{o, Drain};
|
||||
use types::{BitVector, MinimalEthSpec, SubnetId};
|
||||
use unused_port::unused_udp_port;
|
||||
|
||||
type E = MinimalEthSpec;
|
||||
|
||||
@@ -1105,17 +1122,15 @@ mod tests {
|
||||
|
||||
async fn build_discovery() -> Discovery<E> {
|
||||
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
||||
let config = NetworkConfig {
|
||||
discovery_port: unused_udp_port().unwrap(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut config = NetworkConfig::default();
|
||||
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
|
||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
||||
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
||||
let log = build_log(slog::Level::Debug, false);
|
||||
let globals = NetworkGlobals::new(
|
||||
enr,
|
||||
9000,
|
||||
9000,
|
||||
Some(9000),
|
||||
None,
|
||||
MetaData::V2(MetaDataV2 {
|
||||
seq_number: 0,
|
||||
attnets: Default::default(),
|
||||
|
||||
@@ -10,12 +10,14 @@ pub mod service;
|
||||
|
||||
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
||||
pub mod discovery;
|
||||
pub mod listen_addr;
|
||||
pub mod metrics;
|
||||
pub mod peer_manager;
|
||||
pub mod rpc;
|
||||
pub mod types;
|
||||
|
||||
pub use config::gossip_max_size;
|
||||
pub use listen_addr::*;
|
||||
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::str::FromStr;
|
||||
|
||||
97
beacon_node/lighthouse_network/src/listen_addr.rs
Normal file
97
beacon_node/lighthouse_network/src/listen_addr.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
|
||||
use libp2p::{multiaddr::Protocol, Multiaddr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A listening address composed by an Ip, an UDP port and a TCP port.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ListenAddr<Ip> {
|
||||
pub addr: Ip,
|
||||
pub udp_port: u16,
|
||||
pub tcp_port: u16,
|
||||
}
|
||||
|
||||
impl<Ip: Into<IpAddr> + Clone> ListenAddr<Ip> {
|
||||
pub fn udp_socket_addr(&self) -> SocketAddr {
|
||||
(self.addr.clone().into(), self.udp_port).into()
|
||||
}
|
||||
|
||||
pub fn tcp_socket_addr(&self) -> SocketAddr {
|
||||
(self.addr.clone().into(), self.tcp_port).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Types of listening addresses Lighthouse can accept.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum ListenAddress {
|
||||
V4(ListenAddr<Ipv4Addr>),
|
||||
V6(ListenAddr<Ipv6Addr>),
|
||||
DualStack(ListenAddr<Ipv4Addr>, ListenAddr<Ipv6Addr>),
|
||||
}
|
||||
|
||||
impl ListenAddress {
|
||||
/// Return the listening address over IpV4 if any.
|
||||
pub fn v4(&self) -> Option<&ListenAddr<Ipv4Addr>> {
|
||||
match self {
|
||||
ListenAddress::V4(v4_addr) | ListenAddress::DualStack(v4_addr, _) => Some(v4_addr),
|
||||
ListenAddress::V6(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the listening address over IpV6 if any.
|
||||
pub fn v6(&self) -> Option<&ListenAddr<Ipv6Addr>> {
|
||||
match self {
|
||||
ListenAddress::V6(v6_addr) | ListenAddress::DualStack(_, v6_addr) => Some(v6_addr),
|
||||
ListenAddress::V4(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the TCP addresses.
|
||||
pub fn tcp_addresses(&self) -> impl Iterator<Item = Multiaddr> + '_ {
|
||||
let v4_multiaddr = self
|
||||
.v4()
|
||||
.map(|v4_addr| Multiaddr::from(v4_addr.addr).with(Protocol::Tcp(v4_addr.tcp_port)));
|
||||
let v6_multiaddr = self
|
||||
.v6()
|
||||
.map(|v6_addr| Multiaddr::from(v6_addr.addr).with(Protocol::Tcp(v6_addr.tcp_port)));
|
||||
v4_multiaddr.into_iter().chain(v6_multiaddr)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn unused_v4_ports() -> Self {
|
||||
ListenAddress::V4(ListenAddr {
|
||||
addr: Ipv4Addr::UNSPECIFIED,
|
||||
udp_port: unused_port::unused_udp4_port().unwrap(),
|
||||
tcp_port: unused_port::unused_tcp4_port().unwrap(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn unused_v6_ports() -> Self {
|
||||
ListenAddress::V6(ListenAddr {
|
||||
addr: Ipv6Addr::UNSPECIFIED,
|
||||
udp_port: unused_port::unused_udp6_port().unwrap(),
|
||||
tcp_port: unused_port::unused_tcp6_port().unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl slog::KV for ListenAddress {
|
||||
fn serialize(
|
||||
&self,
|
||||
_record: &slog::Record,
|
||||
serializer: &mut dyn slog::Serializer,
|
||||
) -> slog::Result {
|
||||
if let Some(v4_addr) = self.v4() {
|
||||
serializer.emit_arguments("ip4_address", &format_args!("{}", v4_addr.addr))?;
|
||||
serializer.emit_u16("udp4_port", v4_addr.udp_port)?;
|
||||
serializer.emit_u16("tcp4_port", v4_addr.tcp_port)?;
|
||||
}
|
||||
if let Some(v6_addr) = self.v6() {
|
||||
serializer.emit_arguments("ip6_address", &format_args!("{}", v6_addr.addr))?;
|
||||
serializer.emit_u16("udp6_port", v6_addr.udp_port)?;
|
||||
serializer.emit_u16("tcp6_port", v6_addr.tcp_port)?;
|
||||
}
|
||||
slog::Result::Ok(())
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ pub fn check_nat() {
|
||||
if NAT_OPEN.as_ref().map(|v| v.get()).unwrap_or(0) != 0 {
|
||||
return;
|
||||
}
|
||||
if ADDRESS_UPDATE_COUNT.as_ref().map(|v| v.get()).unwrap_or(0) == 0
|
||||
if ADDRESS_UPDATE_COUNT.as_ref().map(|v| v.get()).unwrap_or(0) != 0
|
||||
|| NETWORK_INBOUND_PEERS.as_ref().map(|v| v.get()).unwrap_or(0) != 0_i64
|
||||
{
|
||||
inc_counter(&NAT_OPEN);
|
||||
|
||||
@@ -165,8 +165,8 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
||||
let meta_data = utils::load_or_build_metadata(&config.network_dir, &log);
|
||||
let globals = NetworkGlobals::new(
|
||||
enr,
|
||||
config.libp2p_port,
|
||||
config.discovery_port,
|
||||
config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port),
|
||||
config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port),
|
||||
meta_data,
|
||||
config
|
||||
.trusted_peers
|
||||
@@ -390,36 +390,26 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
||||
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
||||
let enr = self.network_globals.local_enr();
|
||||
info!(self.log, "Libp2p Starting"; "peer_id" => %enr.peer_id(), "bandwidth_config" => format!("{}-{}", config.network_load, NetworkLoad::from(config.network_load).name));
|
||||
let discovery_string = if config.disable_discovery {
|
||||
"None".into()
|
||||
} else {
|
||||
config.discovery_port.to_string()
|
||||
};
|
||||
debug!(self.log, "Attempting to open listening ports"; config.listen_addrs(), "discovery_enabled" => !config.disable_discovery);
|
||||
|
||||
debug!(self.log, "Attempting to open listening ports"; "address" => ?config.listen_address, "tcp_port" => config.libp2p_port, "udp_port" => discovery_string);
|
||||
|
||||
let listen_multiaddr = {
|
||||
let mut m = Multiaddr::from(config.listen_address);
|
||||
m.push(MProtocol::Tcp(config.libp2p_port));
|
||||
m
|
||||
};
|
||||
|
||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||
Ok(_) => {
|
||||
let mut log_address = listen_multiaddr;
|
||||
log_address.push(MProtocol::P2p(enr.peer_id().into()));
|
||||
info!(self.log, "Listening established"; "address" => %log_address);
|
||||
}
|
||||
Err(err) => {
|
||||
crit!(
|
||||
self.log,
|
||||
"Unable to listen on libp2p address";
|
||||
"error" => ?err,
|
||||
"listen_multiaddr" => %listen_multiaddr,
|
||||
);
|
||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||
}
|
||||
};
|
||||
for listen_multiaddr in config.listen_addrs().tcp_addresses() {
|
||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||
Ok(_) => {
|
||||
let mut log_address = listen_multiaddr;
|
||||
log_address.push(MProtocol::P2p(enr.peer_id().into()));
|
||||
info!(self.log, "Listening established"; "address" => %log_address);
|
||||
}
|
||||
Err(err) => {
|
||||
crit!(
|
||||
self.log,
|
||||
"Unable to listen on libp2p address";
|
||||
"error" => ?err,
|
||||
"listen_multiaddr" => %listen_multiaddr,
|
||||
);
|
||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// helper closure for dialing peers
|
||||
let mut dial = |mut multiaddr: Multiaddr| {
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::EnrExt;
|
||||
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
||||
use parking_lot::RwLock;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::atomic::{AtomicU16, Ordering};
|
||||
use types::EthSpec;
|
||||
|
||||
pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
@@ -17,10 +16,10 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
pub peer_id: RwLock<PeerId>,
|
||||
/// Listening multiaddrs.
|
||||
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
||||
/// The TCP port that the libp2p service is listening on
|
||||
pub listen_port_tcp: AtomicU16,
|
||||
/// The UDP port that the discovery service is listening on
|
||||
pub listen_port_udp: AtomicU16,
|
||||
/// The TCP port that the libp2p service is listening on over Ipv4.
|
||||
listen_port_tcp4: Option<u16>,
|
||||
/// The TCP port that the libp2p service is listening on over Ipv6.
|
||||
listen_port_tcp6: Option<u16>,
|
||||
/// The collection of known peers.
|
||||
pub peers: RwLock<PeerDB<TSpec>>,
|
||||
// The local meta data of our node.
|
||||
@@ -36,8 +35,8 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
pub fn new(
|
||||
enr: Enr,
|
||||
tcp_port: u16,
|
||||
udp_port: u16,
|
||||
listen_port_tcp4: Option<u16>,
|
||||
listen_port_tcp6: Option<u16>,
|
||||
local_metadata: MetaData<TSpec>,
|
||||
trusted_peers: Vec<PeerId>,
|
||||
log: &slog::Logger,
|
||||
@@ -46,8 +45,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
local_enr: RwLock::new(enr.clone()),
|
||||
peer_id: RwLock::new(enr.peer_id()),
|
||||
listen_multiaddrs: RwLock::new(Vec::new()),
|
||||
listen_port_tcp: AtomicU16::new(tcp_port),
|
||||
listen_port_udp: AtomicU16::new(udp_port),
|
||||
listen_port_tcp4,
|
||||
listen_port_tcp6,
|
||||
local_metadata: RwLock::new(local_metadata),
|
||||
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
||||
gossipsub_subscriptions: RwLock::new(HashSet::new()),
|
||||
@@ -73,13 +72,13 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
}
|
||||
|
||||
/// Returns the libp2p TCP port that this node has been configured to listen on.
|
||||
pub fn listen_port_tcp(&self) -> u16 {
|
||||
self.listen_port_tcp.load(Ordering::Relaxed)
|
||||
pub fn listen_port_tcp4(&self) -> Option<u16> {
|
||||
self.listen_port_tcp4
|
||||
}
|
||||
|
||||
/// Returns the UDP discovery port that this node has been configured to listen on.
|
||||
pub fn listen_port_udp(&self) -> u16 {
|
||||
self.listen_port_udp.load(Ordering::Relaxed)
|
||||
pub fn listen_port_tcp6(&self) -> Option<u16> {
|
||||
self.listen_port_tcp6
|
||||
}
|
||||
|
||||
/// Returns the number of libp2p connected peers.
|
||||
@@ -137,8 +136,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
let enr = discv5::enr::EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||
NetworkGlobals::new(
|
||||
enr,
|
||||
9000,
|
||||
9000,
|
||||
Some(9000),
|
||||
None,
|
||||
MetaData::V2(MetaDataV2 {
|
||||
seq_number: 0,
|
||||
attnets: Default::default(),
|
||||
|
||||
@@ -13,7 +13,7 @@ use tokio::runtime::Runtime;
|
||||
use types::{
|
||||
ChainSpec, EnrForkId, Epoch, EthSpec, ForkContext, ForkName, Hash256, MinimalEthSpec, Slot,
|
||||
};
|
||||
use unused_port::unused_tcp_port;
|
||||
use unused_port::unused_tcp4_port;
|
||||
|
||||
type E = MinimalEthSpec;
|
||||
type ReqId = usize;
|
||||
@@ -78,11 +78,9 @@ pub fn build_config(port: u16, mut boot_nodes: Vec<Enr>) -> NetworkConfig {
|
||||
.tempdir()
|
||||
.unwrap();
|
||||
|
||||
config.libp2p_port = port; // tcp port
|
||||
config.discovery_port = port; // udp port
|
||||
config.enr_tcp_port = Some(port);
|
||||
config.enr_udp_port = Some(port);
|
||||
config.enr_address = Some("127.0.0.1".parse().unwrap());
|
||||
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, port, port);
|
||||
config.enr_udp4_port = Some(port);
|
||||
config.enr_address = (Some(std::net::Ipv4Addr::LOCALHOST), None);
|
||||
config.boot_nodes_enr.append(&mut boot_nodes);
|
||||
config.network_dir = path.into_path();
|
||||
// Reduce gossipsub heartbeat parameters
|
||||
@@ -100,7 +98,7 @@ pub async fn build_libp2p_instance(
|
||||
log: slog::Logger,
|
||||
fork_name: ForkName,
|
||||
) -> Libp2pInstance {
|
||||
let port = unused_tcp_port().unwrap();
|
||||
let port = unused_tcp4_port().unwrap();
|
||||
let config = build_config(port, boot_nodes);
|
||||
// launch libp2p service
|
||||
|
||||
|
||||
Reference in New Issue
Block a user