Support for Ipv6 (#4046)
## Issue Addressed Add support for ipv6 and dual stack in lighthouse. ## Proposed Changes From an user perspective, now setting an ipv6 address, optionally configuring the ports should feel exactly the same as using an ipv4 address. If listening over both ipv4 and ipv6 then the user needs to: - use the `--listen-address` two times (ipv4 and ipv6 addresses) - `--port6` becomes then required - `--discovery-port6` can now be used to additionally configure the ipv6 udp port ### Rough list of code changes - Discovery: - Table filter and ip mode set to match the listening config. - Ipv6 address, tcp port and udp port set in the ENR builder - Reported addresses now check which tcp port to give to libp2p - LH Network Service: - Can listen over Ipv6, Ipv4, or both. This uses two sockets. Using mapped addresses is disabled from libp2p and it's the most compatible option. - NetworkGlobals: - No longer stores udp port since was not used at all. Instead, stores the Ipv4 and Ipv6 TCP ports. - NetworkConfig: - Update names to make it clear that previous udp and tcp ports in ENR were Ipv4 - Add fields to configure Ipv6 udp and tcp ports in the ENR - Include advertised enr Ipv6 address. - Add type to model Listening address that's either Ipv4, Ipv6 or both. A listening address includes the ip, udp port and tcp port. - UPnP: - Kept only for ipv4 - Cli flags: - `--listen-addresses` now can take up to two values - `--port` will apply to ipv4 or ipv6 if only one listening address is given. If two listening addresses are given it will apply only to Ipv4. - `--port6` New flag required when listening over ipv4 and ipv6 that applies exclusively to Ipv6. - `--discovery-port` will now apply to ipv4 and ipv6 if only one listening address is given. - `--discovery-port6` New flag to configure the individual udp port of ipv6 if listening over both ipv4 and ipv6. - `--enr-udp-port` Updated docs to specify that it only applies to ipv4. This is an old behaviour. - `--enr-udp6-port` Added to configure the enr udp6 field. - `--enr-tcp-port` Updated docs to specify that it only applies to ipv4. This is an old behaviour. - `--enr-tcp6-port` Added to configure the enr tcp6 field. - `--enr-addresses` now can take two values. - `--enr-match` updated behaviour. - Common: - rename `unused_port` functions to specify that they are over ipv4. - add functions to get unused ports over ipv6. - Testing binaries - Updated code to reflect network config changes and unused_port changes. ## Additional Info TODOs: - use two sockets in discovery. I'll get back to this and it's on https://github.com/sigp/discv5/pull/160 - lcli allow listening over two sockets in generate_bootnodes_enr - add at least one smoke flag for ipv6 (I have tested this and works for me) - update the book
This commit is contained in:
parent
06af31a66a
commit
e190ebb8a0
@ -457,7 +457,7 @@ where
|
|||||||
builder_threshold: Option<u128>,
|
builder_threshold: Option<u128>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Get a random unused port
|
// Get a random unused port
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
let builder_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
let builder_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
||||||
|
|
||||||
let spec = self.spec.clone().expect("cannot build without spec");
|
let spec = self.spec.clone().expect("cannot build without spec");
|
||||||
|
@ -46,9 +46,18 @@ impl<T: BeaconChainTypes> Client<T> {
|
|||||||
self.http_metrics_listen_addr
|
self.http_metrics_listen_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the port of the client's libp2p stack, if it was started.
|
/// Returns the ipv4 port of the client's libp2p stack, if it was started.
|
||||||
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
pub fn libp2p_listen_ipv4_port(&self) -> Option<u16> {
|
||||||
self.network_globals.as_ref().map(|n| n.listen_port_tcp())
|
self.network_globals
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|n| n.listen_port_tcp4())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the ipv6 port of the client's libp2p stack, if it was started.
|
||||||
|
pub fn libp2p_listen_ipv6_port(&self) -> Option<u16> {
|
||||||
|
self.network_globals
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|n| n.listen_port_tcp6())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of libp2p addresses the client is listening to.
|
/// Returns the list of libp2p addresses the client is listening to.
|
||||||
|
@ -130,7 +130,7 @@ pub async fn create_api_server<T: BeaconChainTypes>(
|
|||||||
log: Logger,
|
log: Logger,
|
||||||
) -> ApiServer<T::EthSpec, impl Future<Output = ()>> {
|
) -> ApiServer<T::EthSpec, impl Future<Output = ()>> {
|
||||||
// Get a random unused port.
|
// Get a random unused port.
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
create_api_server_on_port(chain, log, port).await
|
create_api_server_on_port(chain, log, port).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,8 +151,8 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
|
|||||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
let network_globals = Arc::new(NetworkGlobals::new(
|
let network_globals = Arc::new(NetworkGlobals::new(
|
||||||
enr.clone(),
|
enr.clone(),
|
||||||
TCP_PORT,
|
Some(TCP_PORT),
|
||||||
UDP_PORT,
|
None,
|
||||||
meta_data,
|
meta_data,
|
||||||
vec![],
|
vec![],
|
||||||
&log,
|
&log,
|
||||||
|
@ -112,7 +112,7 @@ impl ApiTester {
|
|||||||
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
||||||
// Get a random unused port
|
// Get a random unused port
|
||||||
let spec = config.spec;
|
let spec = config.spec;
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
let beacon_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
let beacon_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
||||||
|
|
||||||
let harness = Arc::new(
|
let harness = Arc::new(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::listen_addr::{ListenAddr, ListenAddress};
|
||||||
use crate::rpc::config::OutboundRateLimiterConfig;
|
use crate::rpc::config::OutboundRateLimiterConfig;
|
||||||
use crate::types::GossipKind;
|
use crate::types::GossipKind;
|
||||||
use crate::{Enr, PeerIdSerialized};
|
use crate::{Enr, PeerIdSerialized};
|
||||||
@ -12,6 +13,7 @@ use libp2p::gossipsub::{
|
|||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -57,24 +59,24 @@ pub struct Config {
|
|||||||
/// Data directory where node's keyfile is stored
|
/// Data directory where node's keyfile is stored
|
||||||
pub network_dir: PathBuf,
|
pub network_dir: PathBuf,
|
||||||
|
|
||||||
/// IP address to listen on.
|
/// IP addresses to listen on.
|
||||||
pub listen_address: std::net::IpAddr,
|
listen_addresses: ListenAddress,
|
||||||
|
|
||||||
/// The TCP port that libp2p listens on.
|
|
||||||
pub libp2p_port: u16,
|
|
||||||
|
|
||||||
/// UDP port that discovery listens on.
|
|
||||||
pub discovery_port: u16,
|
|
||||||
|
|
||||||
/// The address to broadcast to peers about which address we are listening on. None indicates
|
/// 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.
|
/// 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.
|
/// The udp4 port to broadcast to peers in order to reach back for discovery.
|
||||||
pub enr_udp_port: Option<u16>,
|
pub enr_udp4_port: Option<u16>,
|
||||||
|
|
||||||
/// The tcp port to broadcast to peers in order to reach back for libp2p services.
|
/// The tcp4 port to broadcast to peers in order to reach back for libp2p services.
|
||||||
pub enr_tcp_port: Option<u16>,
|
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.
|
/// Target number of connected peers.
|
||||||
pub target_peers: usize,
|
pub target_peers: usize,
|
||||||
@ -139,6 +141,105 @@ pub struct Config {
|
|||||||
pub outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
|
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 {
|
impl Default for Config {
|
||||||
/// Generate a default network configuration.
|
/// Generate a default network configuration.
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@ -183,7 +284,7 @@ impl Default for Config {
|
|||||||
.filter_rate_limiter(filter_rate_limiter)
|
.filter_rate_limiter(filter_rate_limiter)
|
||||||
.filter_max_bans_per_ip(Some(5))
|
.filter_max_bans_per_ip(Some(5))
|
||||||
.filter_max_nodes_per_ip(Some(10))
|
.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)))
|
.ban_duration(Some(Duration::from_secs(3600)))
|
||||||
.ping_interval(Duration::from_secs(300))
|
.ping_interval(Duration::from_secs(300))
|
||||||
.build();
|
.build();
|
||||||
@ -191,12 +292,16 @@ impl Default for Config {
|
|||||||
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
||||||
Config {
|
Config {
|
||||||
network_dir,
|
network_dir,
|
||||||
listen_address: "0.0.0.0".parse().expect("valid ip address"),
|
listen_addresses: ListenAddress::V4(ListenAddr {
|
||||||
libp2p_port: 9000,
|
addr: Ipv4Addr::UNSPECIFIED,
|
||||||
discovery_port: 9000,
|
udp_port: 9000,
|
||||||
enr_address: None,
|
tcp_port: 9000,
|
||||||
enr_udp_port: None,
|
}),
|
||||||
enr_tcp_port: None,
|
enr_address: (None, None),
|
||||||
|
enr_udp4_port: None,
|
||||||
|
enr_tcp4_port: None,
|
||||||
|
enr_udp6_port: None,
|
||||||
|
enr_tcp6_port: None,
|
||||||
target_peers: 50,
|
target_peers: 50,
|
||||||
gs_config,
|
gs_config,
|
||||||
discv5_config,
|
discv5_config,
|
||||||
@ -361,7 +466,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()`
|
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
|
||||||
/// function is not yet stable on IpAddr.
|
/// function is not yet stable on IpAddr.
|
||||||
#[allow(clippy::nonminimal_bool)]
|
#[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
|
// 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.
|
// globally routable addresses in the 192.0.0.0/24 range.
|
||||||
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
||||||
@ -382,3 +487,60 @@ fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
|||||||
// Make sure the address is not in 0.0.0.0/8
|
// Make sure the address is not in 0.0.0.0/8
|
||||||
&& addr.octets()[0] != 0
|
&& 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,
|
enable_tcp: bool,
|
||||||
) -> EnrBuilder<T> {
|
) -> EnrBuilder<T> {
|
||||||
let mut builder = EnrBuilder::new("v4");
|
let mut builder = EnrBuilder::new("v4");
|
||||||
if let Some(enr_address) = config.enr_address {
|
let (maybe_ipv4_address, maybe_ipv6_address) = &config.enr_address;
|
||||||
builder.ip(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 {
|
if enable_tcp {
|
||||||
let tcp_port = config.enr_tcp_port.unwrap_or(config.libp2p_port);
|
// If the ENR port is not set, and we are listening over that ip version, use the listening port instead.
|
||||||
builder.tcp4(tcp_port);
|
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
|
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(),
|
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()
|
"ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp6()
|
||||||
);
|
);
|
||||||
|
let listen_socket = match config.listen_addrs() {
|
||||||
let listen_socket = SocketAddr::new(config.listen_address, config.discovery_port);
|
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
|
// convert the keypair into an ENR key
|
||||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
||||||
@ -1015,15 +1020,28 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
|
|||||||
*self.network_globals.local_enr.write() = enr;
|
*self.network_globals.local_enr.write() = enr;
|
||||||
// A new UDP socket has been detected.
|
// A new UDP socket has been detected.
|
||||||
// Build a multiaddr to report to libp2p
|
// Build a multiaddr to report to libp2p
|
||||||
let mut address = Multiaddr::from(socket_addr.ip());
|
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
|
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
||||||
// should handle this.
|
// should handle this.
|
||||||
address.push(Protocol::Tcp(self.network_globals.listen_port_tcp()));
|
|
||||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||||
address,
|
address,
|
||||||
score: AddressScore::Finite(1),
|
score: AddressScore::Finite(1),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Discv5Event::EnrAdded { .. }
|
Discv5Event::EnrAdded { .. }
|
||||||
| Discv5Event::TalkRequest(_)
|
| Discv5Event::TalkRequest(_)
|
||||||
| Discv5Event::NodeInserted { .. }
|
| Discv5Event::NodeInserted { .. }
|
||||||
@ -1087,7 +1105,6 @@ mod tests {
|
|||||||
use enr::EnrBuilder;
|
use enr::EnrBuilder;
|
||||||
use slog::{o, Drain};
|
use slog::{o, Drain};
|
||||||
use types::{BitVector, MinimalEthSpec, SubnetId};
|
use types::{BitVector, MinimalEthSpec, SubnetId};
|
||||||
use unused_port::unused_udp_port;
|
|
||||||
|
|
||||||
type E = MinimalEthSpec;
|
type E = MinimalEthSpec;
|
||||||
|
|
||||||
@ -1105,17 +1122,15 @@ mod tests {
|
|||||||
|
|
||||||
async fn build_discovery() -> Discovery<E> {
|
async fn build_discovery() -> Discovery<E> {
|
||||||
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
||||||
let config = NetworkConfig {
|
let mut config = NetworkConfig::default();
|
||||||
discovery_port: unused_udp_port().unwrap(),
|
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
||||||
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
||||||
let log = build_log(slog::Level::Debug, false);
|
let log = build_log(slog::Level::Debug, false);
|
||||||
let globals = NetworkGlobals::new(
|
let globals = NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
9000,
|
Some(9000),
|
||||||
9000,
|
None,
|
||||||
MetaData::V2(MetaDataV2 {
|
MetaData::V2(MetaDataV2 {
|
||||||
seq_number: 0,
|
seq_number: 0,
|
||||||
attnets: Default::default(),
|
attnets: Default::default(),
|
||||||
|
@ -10,12 +10,14 @@ pub mod service;
|
|||||||
|
|
||||||
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
||||||
pub mod discovery;
|
pub mod discovery;
|
||||||
|
pub mod listen_addr;
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
pub mod peer_manager;
|
pub mod peer_manager;
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use config::gossip_max_size;
|
pub use config::gossip_max_size;
|
||||||
|
pub use listen_addr::*;
|
||||||
|
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::str::FromStr;
|
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(())
|
||||||
|
}
|
||||||
|
}
|
@ -163,8 +163,8 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
let meta_data = utils::load_or_build_metadata(&config.network_dir, &log);
|
let meta_data = utils::load_or_build_metadata(&config.network_dir, &log);
|
||||||
let globals = NetworkGlobals::new(
|
let globals = NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
config.libp2p_port,
|
config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port),
|
||||||
config.discovery_port,
|
config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port),
|
||||||
meta_data,
|
meta_data,
|
||||||
config
|
config
|
||||||
.trusted_peers
|
.trusted_peers
|
||||||
@ -388,20 +388,9 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
||||||
let enr = self.network_globals.local_enr();
|
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));
|
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 {
|
debug!(self.log, "Attempting to open listening ports"; config.listen_addrs(), "discovery_enabled" => !config.disable_discovery);
|
||||||
"None".into()
|
|
||||||
} else {
|
|
||||||
config.discovery_port.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
|
for listen_multiaddr in config.listen_addrs().tcp_addresses() {
|
||||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut log_address = listen_multiaddr;
|
let mut log_address = listen_multiaddr;
|
||||||
@ -418,6 +407,7 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// helper closure for dialing peers
|
// helper closure for dialing peers
|
||||||
let mut dial = |mut multiaddr: Multiaddr| {
|
let mut dial = |mut multiaddr: Multiaddr| {
|
||||||
|
@ -7,7 +7,6 @@ use crate::EnrExt;
|
|||||||
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::atomic::{AtomicU16, Ordering};
|
|
||||||
use types::EthSpec;
|
use types::EthSpec;
|
||||||
|
|
||||||
pub struct NetworkGlobals<TSpec: EthSpec> {
|
pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||||
@ -17,10 +16,10 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
|||||||
pub peer_id: RwLock<PeerId>,
|
pub peer_id: RwLock<PeerId>,
|
||||||
/// Listening multiaddrs.
|
/// Listening multiaddrs.
|
||||||
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
||||||
/// The TCP port that the libp2p service is listening on
|
/// The TCP port that the libp2p service is listening on over Ipv4.
|
||||||
pub listen_port_tcp: AtomicU16,
|
listen_port_tcp4: Option<u16>,
|
||||||
/// The UDP port that the discovery service is listening on
|
/// The TCP port that the libp2p service is listening on over Ipv6.
|
||||||
pub listen_port_udp: AtomicU16,
|
listen_port_tcp6: Option<u16>,
|
||||||
/// The collection of known peers.
|
/// The collection of known peers.
|
||||||
pub peers: RwLock<PeerDB<TSpec>>,
|
pub peers: RwLock<PeerDB<TSpec>>,
|
||||||
// The local meta data of our node.
|
// The local meta data of our node.
|
||||||
@ -36,8 +35,8 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
|||||||
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
enr: Enr,
|
enr: Enr,
|
||||||
tcp_port: u16,
|
listen_port_tcp4: Option<u16>,
|
||||||
udp_port: u16,
|
listen_port_tcp6: Option<u16>,
|
||||||
local_metadata: MetaData<TSpec>,
|
local_metadata: MetaData<TSpec>,
|
||||||
trusted_peers: Vec<PeerId>,
|
trusted_peers: Vec<PeerId>,
|
||||||
log: &slog::Logger,
|
log: &slog::Logger,
|
||||||
@ -46,8 +45,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
|||||||
local_enr: RwLock::new(enr.clone()),
|
local_enr: RwLock::new(enr.clone()),
|
||||||
peer_id: RwLock::new(enr.peer_id()),
|
peer_id: RwLock::new(enr.peer_id()),
|
||||||
listen_multiaddrs: RwLock::new(Vec::new()),
|
listen_multiaddrs: RwLock::new(Vec::new()),
|
||||||
listen_port_tcp: AtomicU16::new(tcp_port),
|
listen_port_tcp4,
|
||||||
listen_port_udp: AtomicU16::new(udp_port),
|
listen_port_tcp6,
|
||||||
local_metadata: RwLock::new(local_metadata),
|
local_metadata: RwLock::new(local_metadata),
|
||||||
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
||||||
gossipsub_subscriptions: RwLock::new(HashSet::new()),
|
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.
|
/// Returns the libp2p TCP port that this node has been configured to listen on.
|
||||||
pub fn listen_port_tcp(&self) -> u16 {
|
pub fn listen_port_tcp4(&self) -> Option<u16> {
|
||||||
self.listen_port_tcp.load(Ordering::Relaxed)
|
self.listen_port_tcp4
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the UDP discovery port that this node has been configured to listen on.
|
/// Returns the UDP discovery port that this node has been configured to listen on.
|
||||||
pub fn listen_port_udp(&self) -> u16 {
|
pub fn listen_port_tcp6(&self) -> Option<u16> {
|
||||||
self.listen_port_udp.load(Ordering::Relaxed)
|
self.listen_port_tcp6
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of libp2p connected peers.
|
/// 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();
|
let enr = discv5::enr::EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
NetworkGlobals::new(
|
NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
9000,
|
Some(9000),
|
||||||
9000,
|
None,
|
||||||
MetaData::V2(MetaDataV2 {
|
MetaData::V2(MetaDataV2 {
|
||||||
seq_number: 0,
|
seq_number: 0,
|
||||||
attnets: Default::default(),
|
attnets: Default::default(),
|
||||||
|
@ -13,7 +13,7 @@ use tokio::runtime::Runtime;
|
|||||||
use types::{
|
use types::{
|
||||||
ChainSpec, EnrForkId, Epoch, EthSpec, ForkContext, ForkName, Hash256, MinimalEthSpec, Slot,
|
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 E = MinimalEthSpec;
|
||||||
type ReqId = usize;
|
type ReqId = usize;
|
||||||
@ -75,11 +75,9 @@ pub fn build_config(port: u16, mut boot_nodes: Vec<Enr>) -> NetworkConfig {
|
|||||||
.tempdir()
|
.tempdir()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
config.libp2p_port = port; // tcp port
|
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, port, port);
|
||||||
config.discovery_port = port; // udp port
|
config.enr_udp4_port = Some(port);
|
||||||
config.enr_tcp_port = Some(port);
|
config.enr_address = (Some(std::net::Ipv4Addr::LOCALHOST), None);
|
||||||
config.enr_udp_port = Some(port);
|
|
||||||
config.enr_address = Some("127.0.0.1".parse().unwrap());
|
|
||||||
config.boot_nodes_enr.append(&mut boot_nodes);
|
config.boot_nodes_enr.append(&mut boot_nodes);
|
||||||
config.network_dir = path.into_path();
|
config.network_dir = path.into_path();
|
||||||
// Reduce gossipsub heartbeat parameters
|
// Reduce gossipsub heartbeat parameters
|
||||||
@ -97,7 +95,7 @@ pub async fn build_libp2p_instance(
|
|||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
fork_name: ForkName,
|
fork_name: ForkName,
|
||||||
) -> Libp2pInstance {
|
) -> Libp2pInstance {
|
||||||
let port = unused_tcp_port().unwrap();
|
let port = unused_tcp4_port().unwrap();
|
||||||
let config = build_config(port, boot_nodes);
|
let config = build_config(port, boot_nodes);
|
||||||
// launch libp2p service
|
// launch libp2p service
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ const SMALL_CHAIN: u64 = 2;
|
|||||||
const LONG_CHAIN: u64 = SLOTS_PER_EPOCH * 2;
|
const LONG_CHAIN: u64 = SLOTS_PER_EPOCH * 2;
|
||||||
|
|
||||||
const TCP_PORT: u16 = 42;
|
const TCP_PORT: u16 = 42;
|
||||||
const UDP_PORT: u16 = 42;
|
|
||||||
const SEQ_NUMBER: u64 = 0;
|
const SEQ_NUMBER: u64 = 0;
|
||||||
|
|
||||||
/// The default time to wait for `BeaconProcessor` events.
|
/// The default time to wait for `BeaconProcessor` events.
|
||||||
@ -177,8 +176,8 @@ impl TestRig {
|
|||||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
let network_globals = Arc::new(NetworkGlobals::new(
|
let network_globals = Arc::new(NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
TCP_PORT,
|
Some(TCP_PORT),
|
||||||
UDP_PORT,
|
None,
|
||||||
meta_data,
|
meta_data,
|
||||||
vec![],
|
vec![],
|
||||||
&log,
|
&log,
|
||||||
|
@ -20,13 +20,13 @@ pub struct UPnPConfig {
|
|||||||
disable_discovery: bool,
|
disable_discovery: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&NetworkConfig> for UPnPConfig {
|
impl UPnPConfig {
|
||||||
fn from(config: &NetworkConfig) -> Self {
|
pub fn from_config(config: &NetworkConfig) -> Option<Self> {
|
||||||
UPnPConfig {
|
config.listen_addrs().v4().map(|v4_addr| UPnPConfig {
|
||||||
tcp_port: config.libp2p_port,
|
tcp_port: v4_addr.tcp_port,
|
||||||
udp_port: config.discovery_port,
|
udp_port: v4_addr.udp_port,
|
||||||
disable_discovery: config.disable_discovery,
|
disable_discovery: config.disable_discovery,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,17 +228,22 @@ impl<T: BeaconChainTypes> NetworkService<T> {
|
|||||||
let (network_senders, network_recievers) = NetworkSenders::new();
|
let (network_senders, network_recievers) = NetworkSenders::new();
|
||||||
|
|
||||||
// try and construct UPnP port mappings if required.
|
// try and construct UPnP port mappings if required.
|
||||||
let upnp_config = crate::nat::UPnPConfig::from(config);
|
if let Some(upnp_config) = crate::nat::UPnPConfig::from_config(config) {
|
||||||
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
||||||
let upnp_network_send = network_senders.network_send();
|
let upnp_network_send = network_senders.network_send();
|
||||||
if config.upnp_enabled {
|
if config.upnp_enabled {
|
||||||
executor.spawn_blocking(
|
executor.spawn_blocking(
|
||||||
move || {
|
move || {
|
||||||
crate::nat::construct_upnp_mappings(upnp_config, upnp_network_send, upnp_log)
|
crate::nat::construct_upnp_mappings(
|
||||||
|
upnp_config,
|
||||||
|
upnp_network_send,
|
||||||
|
upnp_log,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
"UPnP",
|
"UPnP",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get a reference to the beacon chain store
|
// get a reference to the beacon chain store
|
||||||
let store = beacon_chain.store.clone();
|
let store = beacon_chain.store.clone();
|
||||||
|
@ -59,10 +59,9 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut config = NetworkConfig::default();
|
let mut config = NetworkConfig::default();
|
||||||
|
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 21212, 21212);
|
||||||
config.discv5_config.table_filter = |_| true; // Do not ignore local IPs
|
config.discv5_config.table_filter = |_| true; // Do not ignore local IPs
|
||||||
config.libp2p_port = 21212;
|
|
||||||
config.upnp_enabled = false;
|
config.upnp_enabled = false;
|
||||||
config.discovery_port = 21212;
|
|
||||||
config.boot_nodes_enr = enrs.clone();
|
config.boot_nodes_enr = enrs.clone();
|
||||||
runtime.block_on(async move {
|
runtime.block_on(async move {
|
||||||
// Create a new network service which implicitly gets dropped at the
|
// Create a new network service which implicitly gets dropped at the
|
||||||
|
@ -71,7 +71,16 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("listen-address")
|
Arg::with_name("listen-address")
|
||||||
.long("listen-address")
|
.long("listen-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The address lighthouse will listen for UDP and TCP connections.")
|
.help("The address lighthouse will listen for UDP and TCP connections. To listen \
|
||||||
|
over IpV4 and IpV6 set this flag twice with the different values.\n\
|
||||||
|
Examples:\n\
|
||||||
|
- --listen-address '0.0.0.0' will listen over Ipv4.\n\
|
||||||
|
- --listen-address '::' will listen over Ipv6.\n\
|
||||||
|
- --listen-address '0.0.0.0' --listen-address '::' will listen over both \
|
||||||
|
Ipv4 and Ipv6. The order of the given addresses is not relevant. However, \
|
||||||
|
multiple Ipv4, or multiple Ipv6 addresses will not be accepted.")
|
||||||
|
.multiple(true)
|
||||||
|
.max_values(2)
|
||||||
.default_value("0.0.0.0")
|
.default_value("0.0.0.0")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
@ -79,10 +88,21 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("port")
|
Arg::with_name("port")
|
||||||
.long("port")
|
.long("port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
|
.help("The TCP/UDP port to listen on. The UDP port can be modified by the \
|
||||||
|
--discovery-port flag. If listening over both Ipv4 and Ipv6 the --port flag \
|
||||||
|
will apply to the Ipv4 address and --port6 to the Ipv6 address.")
|
||||||
.default_value("9000")
|
.default_value("9000")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("port6")
|
||||||
|
.long("port6")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The TCP/UDP port to listen on over IpV6 when listening over both Ipv4 and \
|
||||||
|
Ipv6. Defaults to 9090 when required.")
|
||||||
|
.default_value("9090")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("discovery-port")
|
Arg::with_name("discovery-port")
|
||||||
.long("discovery-port")
|
.long("discovery-port")
|
||||||
@ -90,6 +110,15 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.help("The UDP port that discovery will listen on. Defaults to `port`")
|
.help("The UDP port that discovery will listen on. Defaults to `port`")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("discovery-port6")
|
||||||
|
.long("discovery-port6")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP port that discovery will listen on over IpV6 if listening over \
|
||||||
|
both Ipv4 and IpV6. Defaults to `port6`")
|
||||||
|
.hidden(true) // TODO: implement dual stack via two sockets in discv5.
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("target-peers")
|
Arg::with_name("target-peers")
|
||||||
.long("target-peers")
|
.long("target-peers")
|
||||||
@ -130,27 +159,49 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("enr-udp-port")
|
Arg::with_name("enr-udp-port")
|
||||||
.long("enr-udp-port")
|
.long("enr-udp-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The UDP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.")
|
.help("The UDP4 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV4.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-udp6-port")
|
||||||
|
.long("enr-udp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enr-tcp-port")
|
Arg::with_name("enr-tcp-port")
|
||||||
.long("enr-tcp-port")
|
.long("enr-tcp-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The TCP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.\
|
.help("The TCP4 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
The --port flag is used if this is not set.")
|
can connect to your local node on this port over IpV4. The --port flag is \
|
||||||
|
used if this is not set.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-tcp6-port")
|
||||||
|
.long("enr-tcp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The TCP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6. The --port6 flag is \
|
||||||
|
used if this is not set.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enr-address")
|
Arg::with_name("enr-address")
|
||||||
.long("enr-address")
|
.long("enr-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The IP address/ DNS address to broadcast to other peers on how to reach this node. \
|
.help("The IP address/ DNS address to broadcast to other peers on how to reach \
|
||||||
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
|
this node. If a DNS address is provided, the enr-address is set to the IP \
|
||||||
does not auto-update based on PONG responses in discovery. \
|
address it resolves to and does not auto-update based on PONG responses in \
|
||||||
Set this only if you are sure other nodes can connect to your local node on this address. \
|
discovery. Set this only if you are sure other nodes can connect to your \
|
||||||
Discovery will automatically find your external address, if possible.")
|
local node on this address. This will update the `ip4` or `ip6` ENR fields \
|
||||||
|
accordingly. To update both, set this flag twice with the different values.")
|
||||||
.requires("enr-udp-port")
|
.requires("enr-udp-port")
|
||||||
|
.multiple(true)
|
||||||
|
.max_values(2)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@ -158,7 +209,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.short("e")
|
.short("e")
|
||||||
.long("enr-match")
|
.long("enr-match")
|
||||||
.help("Sets the local ENR IP address and port to match those set for lighthouse. \
|
.help("Sets the local ENR IP address and port to match those set for lighthouse. \
|
||||||
Specifically, the IP address will be the value of --listen-address and the UDP port will be --discovery-port.")
|
Specifically, the IP address will be the value of --listen-address and the \
|
||||||
|
UDP port will be --discovery-port.")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("disable-enr-auto-update")
|
Arg::with_name("disable-enr-auto-update")
|
||||||
|
@ -10,13 +10,13 @@ use environment::RuntimeContext;
|
|||||||
use execution_layer::DEFAULT_JWT_FILE;
|
use execution_layer::DEFAULT_JWT_FILE;
|
||||||
use genesis::Eth1Endpoint;
|
use genesis::Eth1Endpoint;
|
||||||
use http_api::TlsConfig;
|
use http_api::TlsConfig;
|
||||||
|
use lighthouse_network::ListenAddress;
|
||||||
use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
|
use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use slog::{info, warn, Logger};
|
use slog::{info, warn, Logger};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fmt::Write;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::net::Ipv6Addr;
|
use std::net::Ipv6Addr;
|
||||||
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
|
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
|
||||||
@ -24,7 +24,6 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use types::{Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, GRAFFITI_BYTES_LEN};
|
use types::{Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, GRAFFITI_BYTES_LEN};
|
||||||
use unused_port::{unused_tcp_port, unused_udp_port};
|
|
||||||
|
|
||||||
/// Gets the fully-initialized global client.
|
/// Gets the fully-initialized global client.
|
||||||
///
|
///
|
||||||
@ -78,13 +77,7 @@ pub fn get_config<E: EthSpec>(
|
|||||||
|
|
||||||
let data_dir_ref = client_config.data_dir().clone();
|
let data_dir_ref = client_config.data_dir().clone();
|
||||||
|
|
||||||
set_network_config(
|
set_network_config(&mut client_config.network, cli_args, &data_dir_ref, log)?;
|
||||||
&mut client_config.network,
|
|
||||||
cli_args,
|
|
||||||
&data_dir_ref,
|
|
||||||
log,
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Staking flag
|
* Staking flag
|
||||||
@ -404,13 +397,6 @@ pub fn get_config<E: EthSpec>(
|
|||||||
* Discovery address is set to localhost by default.
|
* Discovery address is set to localhost by default.
|
||||||
*/
|
*/
|
||||||
if cli_args.is_present("zero-ports") {
|
if cli_args.is_present("zero-ports") {
|
||||||
if client_config.network.enr_address == Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))) {
|
|
||||||
client_config.network.enr_address = None
|
|
||||||
}
|
|
||||||
client_config.network.libp2p_port =
|
|
||||||
unused_tcp_port().map_err(|e| format!("Failed to get port for libp2p: {}", e))?;
|
|
||||||
client_config.network.discovery_port =
|
|
||||||
unused_udp_port().map_err(|e| format!("Failed to get port for discovery: {}", e))?;
|
|
||||||
client_config.http_api.listen_port = 0;
|
client_config.http_api.listen_port = 0;
|
||||||
client_config.http_metrics.listen_port = 0;
|
client_config.http_metrics.listen_port = 0;
|
||||||
}
|
}
|
||||||
@ -761,13 +747,177 @@ pub fn get_config<E: EthSpec>(
|
|||||||
Ok(client_config)
|
Ok(client_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the network config from the command line arguments
|
/// Gets the listening_addresses for lighthouse based on the cli options.
|
||||||
|
pub fn parse_listening_addresses(
|
||||||
|
cli_args: &ArgMatches,
|
||||||
|
log: &Logger,
|
||||||
|
) -> Result<ListenAddress, String> {
|
||||||
|
let listen_addresses_str = cli_args
|
||||||
|
.values_of("listen-address")
|
||||||
|
.expect("--listen_addresses has a default value");
|
||||||
|
|
||||||
|
let use_zero_ports = cli_args.is_present("zero-ports");
|
||||||
|
|
||||||
|
// parse the possible ips
|
||||||
|
let mut maybe_ipv4 = None;
|
||||||
|
let mut maybe_ipv6 = None;
|
||||||
|
for addr_str in listen_addresses_str {
|
||||||
|
let addr = addr_str.parse::<IpAddr>().map_err(|parse_error| {
|
||||||
|
format!("Failed to parse listen-address ({addr_str}) as an Ip address: {parse_error}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
IpAddr::V4(v4_addr) => match &maybe_ipv4 {
|
||||||
|
Some(first_ipv4_addr) => {
|
||||||
|
return Err(format!(
|
||||||
|
"When setting the --listen-address option twice, use an IpV4 address and an Ipv6 address. \
|
||||||
|
Got two IpV4 addresses {first_ipv4_addr} and {v4_addr}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None => maybe_ipv4 = Some(v4_addr),
|
||||||
|
},
|
||||||
|
IpAddr::V6(v6_addr) => match &maybe_ipv6 {
|
||||||
|
Some(first_ipv6_addr) => {
|
||||||
|
return Err(format!(
|
||||||
|
"When setting the --listen-address option twice, use an IpV4 address and an Ipv6 address. \
|
||||||
|
Got two IpV6 addresses {first_ipv6_addr} and {v6_addr}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None => maybe_ipv6 = Some(v6_addr),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the possible tcp ports
|
||||||
|
let port = cli_args
|
||||||
|
.value_of("port")
|
||||||
|
.expect("--port has a default value")
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|parse_error| format!("Failed to parse --port as an integer: {parse_error}"))?;
|
||||||
|
let port6 = cli_args
|
||||||
|
.value_of("port6")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| format!("Failed to parse --port6 as an integer: {parse_error}"))?
|
||||||
|
.unwrap_or(9090);
|
||||||
|
|
||||||
|
// parse the possible udp ports
|
||||||
|
let maybe_udp_port = cli_args
|
||||||
|
.value_of("discovery-port")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| {
|
||||||
|
format!("Failed to parse --discovery-port as an integer: {parse_error}")
|
||||||
|
})?;
|
||||||
|
let maybe_udp6_port = cli_args
|
||||||
|
.value_of("discovery-port6")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| {
|
||||||
|
format!("Failed to parse --discovery-port6 as an integer: {parse_error}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Now put everything together
|
||||||
|
let listening_addresses = match (maybe_ipv4, maybe_ipv6) {
|
||||||
|
(None, None) => {
|
||||||
|
// This should never happen unless clap is broken
|
||||||
|
return Err("No listening addresses provided".into());
|
||||||
|
}
|
||||||
|
(None, Some(ipv6)) => {
|
||||||
|
// A single ipv6 address was provided. Set the ports
|
||||||
|
|
||||||
|
if cli_args.is_present("port6") {
|
||||||
|
warn!(log, "When listening only over IpV6, use the --port flag. The value of --port6 will be ignored.")
|
||||||
|
}
|
||||||
|
// use zero ports if required. If not, use the given port.
|
||||||
|
let tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
|
||||||
|
if maybe_udp6_port.is_some() {
|
||||||
|
warn!(log, "When listening only over IpV6, use the --discovery-port flag. The value of --discovery-port6 will be ignored.")
|
||||||
|
}
|
||||||
|
// use zero ports if required. If not, use the specific udp port. If none given, use
|
||||||
|
// the tcp port.
|
||||||
|
let udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(port);
|
||||||
|
|
||||||
|
ListenAddress::V6(lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv6,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(Some(ipv4), None) => {
|
||||||
|
// A single ipv4 address was provided. Set the ports
|
||||||
|
|
||||||
|
// use zero ports if required. If not, use the given port.
|
||||||
|
let tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
// use zero ports if required. If not, use the specific udp port. If none given, use
|
||||||
|
// the tcp port.
|
||||||
|
let udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(port);
|
||||||
|
ListenAddress::V4(lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv4,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(Some(ipv4), Some(ipv6)) => {
|
||||||
|
let ipv4_tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
let ipv4_udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(ipv4_tcp_port);
|
||||||
|
|
||||||
|
// Defaults to 9090 when required
|
||||||
|
let ipv6_tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port6);
|
||||||
|
let ipv6_udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp6_port)
|
||||||
|
.unwrap_or(ipv6_tcp_port);
|
||||||
|
ListenAddress::DualStack(
|
||||||
|
lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv4,
|
||||||
|
udp_port: ipv4_udp_port,
|
||||||
|
tcp_port: ipv4_tcp_port,
|
||||||
|
},
|
||||||
|
lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv6,
|
||||||
|
udp_port: ipv6_udp_port,
|
||||||
|
tcp_port: ipv6_tcp_port,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(listening_addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the network config from the command line arguments.
|
||||||
pub fn set_network_config(
|
pub fn set_network_config(
|
||||||
config: &mut NetworkConfig,
|
config: &mut NetworkConfig,
|
||||||
cli_args: &ArgMatches,
|
cli_args: &ArgMatches,
|
||||||
data_dir: &Path,
|
data_dir: &Path,
|
||||||
log: &Logger,
|
log: &Logger,
|
||||||
use_listening_port_as_enr_port_by_default: bool,
|
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// If a network dir has been specified, override the `datadir` definition.
|
// If a network dir has been specified, override the `datadir` definition.
|
||||||
if let Some(dir) = cli_args.value_of("network-dir") {
|
if let Some(dir) = cli_args.value_of("network-dir") {
|
||||||
@ -788,12 +938,7 @@ pub fn set_network_config(
|
|||||||
config.shutdown_after_sync = true;
|
config.shutdown_after_sync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(listen_address_str) = cli_args.value_of("listen-address") {
|
config.set_listening_addr(parse_listening_addresses(cli_args, log)?);
|
||||||
let listen_address = listen_address_str
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| format!("Invalid listen address: {:?}", listen_address_str))?;
|
|
||||||
config.listen_address = listen_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
|
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
|
||||||
config.target_peers = target_peers_str
|
config.target_peers = target_peers_str
|
||||||
@ -801,21 +946,6 @@ pub fn set_network_config(
|
|||||||
.map_err(|_| format!("Invalid number of target peers: {}", target_peers_str))?;
|
.map_err(|_| format!("Invalid number of target peers: {}", target_peers_str))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(port_str) = cli_args.value_of("port") {
|
|
||||||
let port = port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid port: {}", port_str))?;
|
|
||||||
config.libp2p_port = port;
|
|
||||||
config.discovery_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(port_str) = cli_args.value_of("discovery-port") {
|
|
||||||
let port = port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid port: {}", port_str))?;
|
|
||||||
config.discovery_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(value) = cli_args.value_of("network-load") {
|
if let Some(value) = cli_args.value_of("network-load") {
|
||||||
let network_load = value
|
let network_load = value
|
||||||
.parse::<u8>()
|
.parse::<u8>()
|
||||||
@ -871,7 +1001,7 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
|
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
|
||||||
config.enr_udp_port = Some(
|
config.enr_udp4_port = Some(
|
||||||
enr_udp_port_str
|
enr_udp_port_str
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
||||||
@ -879,7 +1009,23 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp-port") {
|
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp-port") {
|
||||||
config.enr_tcp_port = Some(
|
config.enr_tcp4_port = Some(
|
||||||
|
enr_tcp_port_str
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp6-port") {
|
||||||
|
config.enr_udp6_port = Some(
|
||||||
|
enr_udp_port_str
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp6-port") {
|
||||||
|
config.enr_tcp6_port = Some(
|
||||||
enr_tcp_port_str
|
enr_tcp_port_str
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
||||||
@ -887,58 +1033,106 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cli_args.is_present("enr-match") {
|
if cli_args.is_present("enr-match") {
|
||||||
|
// Match the Ip and UDP port in the enr.
|
||||||
|
|
||||||
// set the enr address to localhost if the address is unspecified
|
// set the enr address to localhost if the address is unspecified
|
||||||
if config.listen_address == IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
|
if let Some(ipv4_addr) = config.listen_addrs().v4().cloned() {
|
||||||
config.enr_address = Some(IpAddr::V4(Ipv4Addr::LOCALHOST));
|
let ipv4_enr_addr = if ipv4_addr.addr == Ipv4Addr::UNSPECIFIED {
|
||||||
} else if config.listen_address == IpAddr::V6(Ipv6Addr::UNSPECIFIED) {
|
Ipv4Addr::LOCALHOST
|
||||||
config.enr_address = Some(IpAddr::V6(Ipv6Addr::LOCALHOST));
|
|
||||||
} else {
|
} else {
|
||||||
config.enr_address = Some(config.listen_address);
|
ipv4_addr.addr
|
||||||
}
|
};
|
||||||
config.enr_udp_port = Some(config.discovery_port);
|
config.enr_address.0 = Some(ipv4_enr_addr);
|
||||||
|
config.enr_udp4_port = Some(ipv4_addr.udp_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_address) = cli_args.value_of("enr-address") {
|
if let Some(ipv6_addr) = config.listen_addrs().v6().cloned() {
|
||||||
let resolved_addr = match enr_address.parse::<IpAddr>() {
|
let ipv6_enr_addr = if ipv6_addr.addr == Ipv6Addr::UNSPECIFIED {
|
||||||
Ok(addr) => addr, // // Input is an IpAddr
|
Ipv6Addr::LOCALHOST
|
||||||
|
} else {
|
||||||
|
ipv6_addr.addr
|
||||||
|
};
|
||||||
|
config.enr_address.1 = Some(ipv6_enr_addr);
|
||||||
|
config.enr_udp6_port = Some(ipv6_addr.udp_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_addresses) = cli_args.values_of("enr-address") {
|
||||||
|
let mut enr_ip4 = None;
|
||||||
|
let mut enr_ip6 = None;
|
||||||
|
let mut resolved_enr_ip4 = None;
|
||||||
|
let mut resolved_enr_ip6 = None;
|
||||||
|
|
||||||
|
for addr in enr_addresses {
|
||||||
|
match addr.parse::<IpAddr>() {
|
||||||
|
Ok(IpAddr::V4(v4_addr)) => {
|
||||||
|
if let Some(used) = enr_ip4.as_ref() {
|
||||||
|
warn!(log, "More than one Ipv4 ENR address provided"; "used" => %used, "ignored" => %v4_addr)
|
||||||
|
} else {
|
||||||
|
enr_ip4 = Some(v4_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(IpAddr::V6(v6_addr)) => {
|
||||||
|
if let Some(used) = enr_ip6.as_ref() {
|
||||||
|
warn!(log, "More than one Ipv6 ENR address provided"; "used" => %used, "ignored" => %v6_addr)
|
||||||
|
} else {
|
||||||
|
enr_ip6 = Some(v6_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let mut addr = enr_address.to_string();
|
// Try to resolve the address
|
||||||
// Appending enr-port to the dns hostname to appease `to_socket_addrs()` parsing.
|
|
||||||
// Since enr-update is disabled with a dns address, not setting the enr-udp-port
|
// NOTE: From checking the `to_socket_addrs` code I don't think the port
|
||||||
// will make the node undiscoverable.
|
// actually matters. Just use the udp port.
|
||||||
if let Some(enr_udp_port) =
|
|
||||||
config
|
let port = match config.listen_addrs() {
|
||||||
.enr_udp_port
|
ListenAddress::V4(v4_addr) => v4_addr.udp_port,
|
||||||
.or(if use_listening_port_as_enr_port_by_default {
|
ListenAddress::V6(v6_addr) => v6_addr.udp_port,
|
||||||
Some(config.discovery_port)
|
ListenAddress::DualStack(v4_addr, _v6_addr) => {
|
||||||
} else {
|
// NOTE: slight preference for ipv4 that I don't think is of importance.
|
||||||
None
|
v4_addr.udp_port
|
||||||
})
|
|
||||||
{
|
|
||||||
write!(addr, ":{}", enr_udp_port)
|
|
||||||
.map_err(|e| format!("Failed to write enr address {}", e))?;
|
|
||||||
} else {
|
|
||||||
return Err(
|
|
||||||
"enr-udp-port must be set for node to be discoverable with dns address"
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// `to_socket_addr()` does the dns resolution
|
|
||||||
// Note: `to_socket_addrs()` is a blocking call
|
|
||||||
let resolved_addr = if let Ok(mut resolved_addrs) = addr.to_socket_addrs() {
|
|
||||||
// Pick the first ip from the list of resolved addresses
|
|
||||||
resolved_addrs
|
|
||||||
.next()
|
|
||||||
.map(|a| a.ip())
|
|
||||||
.ok_or("Resolved dns addr contains no entries")?
|
|
||||||
} else {
|
|
||||||
return Err(format!("Failed to parse enr-address: {}", enr_address));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let addr_str = format!("{addr}:{port}");
|
||||||
|
match addr_str.to_socket_addrs() {
|
||||||
|
Err(_e) => {
|
||||||
|
return Err(format!("Failed to parse or resolve address {addr}."))
|
||||||
|
}
|
||||||
|
Ok(resolved_addresses) => {
|
||||||
|
for socket_addr in resolved_addresses {
|
||||||
|
// Use the first ipv4 and first ipv6 addresses present.
|
||||||
|
|
||||||
|
// NOTE: this means that if two dns addresses are provided, we
|
||||||
|
// might end up using the ipv4 and ipv6 resolved addresses of just
|
||||||
|
// the first.
|
||||||
|
match socket_addr.ip() {
|
||||||
|
IpAddr::V4(v4_addr) => {
|
||||||
|
if resolved_enr_ip4.is_none() {
|
||||||
|
resolved_enr_ip4 = Some(v4_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IpAddr::V6(v6_addr) => {
|
||||||
|
if resolved_enr_ip6.is_none() {
|
||||||
|
resolved_enr_ip6 = Some(v6_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ENR addresses given as ips should take preference over any resolved address
|
||||||
|
let used_host_resolution = resolved_enr_ip4.is_some() || resolved_enr_ip6.is_some();
|
||||||
|
let ip4 = enr_ip4.or(resolved_enr_ip4);
|
||||||
|
let ip6 = enr_ip6.or(resolved_enr_ip6);
|
||||||
|
config.enr_address = (ip4, ip6);
|
||||||
|
if used_host_resolution {
|
||||||
config.discv5_config.enr_update = false;
|
config.discv5_config.enr_update = false;
|
||||||
resolved_addr
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
config.enr_address = Some(resolved_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cli_args.is_present("disable-enr-auto-update") {
|
if cli_args.is_present("disable-enr-auto-update") {
|
||||||
|
@ -53,6 +53,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.conflicts_with("network-dir")
|
.conflicts_with("network-dir")
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-udp6-port")
|
||||||
|
.long("enr-udp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enable-enr-auto-update")
|
Arg::with_name("enable-enr-auto-update")
|
||||||
.short("x")
|
.short("x")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use beacon_node::{get_data_dir, set_network_config};
|
use beacon_node::{get_data_dir, set_network_config};
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use eth2_network_config::Eth2NetworkConfig;
|
use eth2_network_config::Eth2NetworkConfig;
|
||||||
use lighthouse_network::discv5::enr::EnrBuilder;
|
use lighthouse_network::discovery::create_enr_builder_from_config;
|
||||||
use lighthouse_network::discv5::IpMode;
|
use lighthouse_network::discv5::IpMode;
|
||||||
use lighthouse_network::discv5::{enr::CombinedKey, Discv5Config, Enr};
|
use lighthouse_network::discv5::{enr::CombinedKey, Discv5Config, Enr};
|
||||||
use lighthouse_network::{
|
use lighthouse_network::{
|
||||||
@ -57,12 +57,24 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
|
|
||||||
let logger = slog_scope::logger();
|
let logger = slog_scope::logger();
|
||||||
|
|
||||||
set_network_config(&mut network_config, matches, &data_dir, &logger, true)?;
|
set_network_config(&mut network_config, matches, &data_dir, &logger)?;
|
||||||
|
|
||||||
// Set the enr-udp-port to the default listening port if it was not specified.
|
// Set the Enr UDP ports to the listening ports if not present.
|
||||||
if !matches.is_present("enr-udp-port") {
|
if let Some(listening_addr_v4) = network_config.listen_addrs().v4() {
|
||||||
network_config.enr_udp_port = Some(network_config.discovery_port);
|
network_config.enr_udp4_port = Some(
|
||||||
}
|
network_config
|
||||||
|
.enr_udp4_port
|
||||||
|
.unwrap_or(listening_addr_v4.udp_port),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(listening_addr_v6) = network_config.listen_addrs().v6() {
|
||||||
|
network_config.enr_udp6_port = Some(
|
||||||
|
network_config
|
||||||
|
.enr_udp6_port
|
||||||
|
.unwrap_or(listening_addr_v6.udp_port),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// By default this is enabled. If it is not set, revert to false.
|
// By default this is enabled. If it is not set, revert to false.
|
||||||
if !matches.is_present("enable-enr-auto-update") {
|
if !matches.is_present("enable-enr-auto-update") {
|
||||||
@ -70,17 +82,29 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the address to listen on
|
// the address to listen on
|
||||||
let listen_socket =
|
let listen_socket = match network_config.listen_addrs().clone() {
|
||||||
SocketAddr::new(network_config.listen_address, network_config.discovery_port);
|
lighthouse_network::ListenAddress::V4(v4_addr) => {
|
||||||
if listen_socket.is_ipv6() {
|
// Set explicitly as ipv4 otherwise
|
||||||
|
network_config.discv5_config.ip_mode = IpMode::Ip4;
|
||||||
|
v4_addr.udp_socket_addr()
|
||||||
|
}
|
||||||
|
lighthouse_network::ListenAddress::V6(v6_addr) => {
|
||||||
|
// create ipv6 sockets and enable ipv4 mapped addresses.
|
||||||
|
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||||
|
enable_mapped_addresses: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
v6_addr.udp_socket_addr()
|
||||||
|
}
|
||||||
|
lighthouse_network::ListenAddress::DualStack(_v4_addr, v6_addr) => {
|
||||||
// create ipv6 sockets and enable ipv4 mapped addresses.
|
// create ipv6 sockets and enable ipv4 mapped addresses.
|
||||||
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||||
enable_mapped_addresses: true,
|
enable_mapped_addresses: true,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
// Set explicitly as ipv4 otherwise
|
v6_addr.udp_socket_addr()
|
||||||
network_config.discv5_config.ip_mode = IpMode::Ip4;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let private_key = load_private_key(&network_config, &logger);
|
let private_key = load_private_key(&network_config, &logger);
|
||||||
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
||||||
@ -115,30 +139,8 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
// Build the local ENR
|
// Build the local ENR
|
||||||
|
|
||||||
let mut local_enr = {
|
let mut local_enr = {
|
||||||
let mut builder = EnrBuilder::new("v4");
|
let enable_tcp = false;
|
||||||
// Set the enr address if specified. Set also the port.
|
let mut builder = create_enr_builder_from_config(&network_config, enable_tcp);
|
||||||
// NOTE: if the port is specified but the the address is not, the port won't be
|
|
||||||
// set since it can't be known if it's an ipv6 or ipv4 udp port.
|
|
||||||
if let Some(enr_address) = network_config.enr_address {
|
|
||||||
match enr_address {
|
|
||||||
std::net::IpAddr::V4(ipv4_addr) => {
|
|
||||||
builder.ip4(ipv4_addr);
|
|
||||||
if let Some(port) = network_config.enr_udp_port {
|
|
||||||
builder.udp4(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::net::IpAddr::V6(ipv6_addr) => {
|
|
||||||
builder.ip6(ipv6_addr);
|
|
||||||
if let Some(port) = network_config.enr_udp_port {
|
|
||||||
builder.udp6(port);
|
|
||||||
// We are enabling mapped addresses in the boot node in this case,
|
|
||||||
// so advertise an udp4 port as well.
|
|
||||||
builder.udp4(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we know of the ENR field, add it to the initial construction
|
// If we know of the ENR field, add it to the initial construction
|
||||||
if let Some(enr_fork_bytes) = enr_fork {
|
if let Some(enr_fork_bytes) = enr_fork {
|
||||||
builder.add_value("eth2", enr_fork_bytes.as_slice());
|
builder.add_value("eth2", enr_fork_bytes.as_slice());
|
||||||
|
@ -6,14 +6,30 @@ pub enum Transport {
|
|||||||
Udp,
|
Udp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
#[derive(Copy, Clone)]
|
||||||
pub fn unused_tcp_port() -> Result<u16, String> {
|
pub enum IpVersion {
|
||||||
unused_port(Transport::Tcp)
|
Ipv4,
|
||||||
|
Ipv6,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
/// A convenience wrapper over [`zero_port`].
|
||||||
pub fn unused_udp_port() -> Result<u16, String> {
|
pub fn unused_tcp4_port() -> Result<u16, String> {
|
||||||
unused_port(Transport::Udp)
|
zero_port(Transport::Tcp, IpVersion::Ipv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_udp4_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Udp, IpVersion::Ipv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_tcp6_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Tcp, IpVersion::Ipv6)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_udp6_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Udp, IpVersion::Ipv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A bit of hack to find an unused port.
|
/// A bit of hack to find an unused port.
|
||||||
@ -26,10 +42,15 @@ pub fn unused_udp_port() -> Result<u16, String> {
|
|||||||
/// It is possible that users are unable to bind to the ports returned by this function as the OS
|
/// It is possible that users are unable to bind to the ports returned by this function as the OS
|
||||||
/// has a buffer period where it doesn't allow binding to the same port even after the socket is
|
/// has a buffer period where it doesn't allow binding to the same port even after the socket is
|
||||||
/// closed. We might have to use SO_REUSEADDR socket option from `std::net2` crate in that case.
|
/// closed. We might have to use SO_REUSEADDR socket option from `std::net2` crate in that case.
|
||||||
pub fn unused_port(transport: Transport) -> Result<u16, String> {
|
pub fn zero_port(transport: Transport, ipv: IpVersion) -> Result<u16, String> {
|
||||||
|
let localhost = match ipv {
|
||||||
|
IpVersion::Ipv4 => std::net::Ipv4Addr::LOCALHOST.into(),
|
||||||
|
IpVersion::Ipv6 => std::net::Ipv6Addr::LOCALHOST.into(),
|
||||||
|
};
|
||||||
|
let socket_addr = std::net::SocketAddr::new(localhost, 0);
|
||||||
let local_addr = match transport {
|
let local_addr = match transport {
|
||||||
Transport::Tcp => {
|
Transport::Tcp => {
|
||||||
let listener = TcpListener::bind("127.0.0.1:0").map_err(|e| {
|
let listener = TcpListener::bind(socket_addr).map_err(|e| {
|
||||||
format!("Failed to create TCP listener to find unused port: {:?}", e)
|
format!("Failed to create TCP listener to find unused port: {:?}", e)
|
||||||
})?;
|
})?;
|
||||||
listener.local_addr().map_err(|e| {
|
listener.local_addr().map_err(|e| {
|
||||||
@ -40,7 +61,7 @@ pub fn unused_port(transport: Transport) -> Result<u16, String> {
|
|||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
Transport::Udp => {
|
Transport::Udp => {
|
||||||
let socket = UdpSocket::bind("127.0.0.1:0")
|
let socket = UdpSocket::bind(socket_addr)
|
||||||
.map_err(|e| format!("Failed to create UDP socket to find unused port: {:?}", e))?;
|
.map_err(|e| format!("Failed to create UDP socket to find unused port: {:?}", e))?;
|
||||||
socket.local_addr().map_err(|e| {
|
socket.local_addr().map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
|
@ -3,15 +3,14 @@ use lighthouse_network::{
|
|||||||
discovery::{build_enr, CombinedKey, CombinedKeyExt, Keypair, ENR_FILENAME},
|
discovery::{build_enr, CombinedKey, CombinedKeyExt, Keypair, ENR_FILENAME},
|
||||||
NetworkConfig, NETWORK_KEY_FILENAME,
|
NetworkConfig, NETWORK_KEY_FILENAME,
|
||||||
};
|
};
|
||||||
use std::fs;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::IpAddr;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::{fs, net::Ipv4Addr};
|
||||||
use types::{ChainSpec, EnrForkId, Epoch, EthSpec, Hash256};
|
use types::{ChainSpec, EnrForkId, Epoch, EthSpec, Hash256};
|
||||||
|
|
||||||
pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
||||||
let ip: IpAddr = clap_utils::parse_required(matches, "ip")?;
|
let ip: Ipv4Addr = clap_utils::parse_required(matches, "ip")?;
|
||||||
let udp_port: u16 = clap_utils::parse_required(matches, "udp-port")?;
|
let udp_port: u16 = clap_utils::parse_required(matches, "udp-port")?;
|
||||||
let tcp_port: u16 = clap_utils::parse_required(matches, "tcp-port")?;
|
let tcp_port: u16 = clap_utils::parse_required(matches, "tcp-port")?;
|
||||||
let output_dir: PathBuf = clap_utils::parse_required(matches, "output-dir")?;
|
let output_dir: PathBuf = clap_utils::parse_required(matches, "output-dir")?;
|
||||||
@ -25,12 +24,10 @@ pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = NetworkConfig {
|
let mut config = NetworkConfig::default();
|
||||||
enr_address: Some(ip),
|
config.enr_address = (Some(ip), None);
|
||||||
enr_udp_port: Some(udp_port),
|
config.enr_udp4_port = Some(udp_port);
|
||||||
enr_tcp_port: Some(tcp_port),
|
config.enr_tcp6_port = Some(tcp_port);
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let local_keypair = Keypair::generate_secp256k1();
|
let local_keypair = Keypair::generate_secp256k1();
|
||||||
let enr_key = CombinedKey::from_libp2p(&local_keypair)?;
|
let enr_key = CombinedKey::from_libp2p(&local_keypair)?;
|
||||||
|
@ -8,7 +8,7 @@ use eth1::Eth1Endpoint;
|
|||||||
use lighthouse_network::PeerId;
|
use lighthouse_network::PeerId;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::IpAddr;
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -16,7 +16,7 @@ use std::string::ToString;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, ForkName, Hash256, MainnetEthSpec};
|
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, ForkName, Hash256, MainnetEthSpec};
|
||||||
use unused_port::{unused_tcp_port, unused_udp_port};
|
use unused_port::{unused_tcp4_port, unused_tcp6_port, unused_udp4_port, unused_udp6_port};
|
||||||
|
|
||||||
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
||||||
|
|
||||||
@ -851,37 +851,188 @@ fn network_shutdown_after_sync_disabled_flag() {
|
|||||||
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_listen_address_flag() {
|
fn network_listen_address_flag_v4() {
|
||||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.listen_address, addr));
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|addr| addr.addr),
|
||||||
|
Some(addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_port_flag() {
|
fn network_listen_address_flag_v6() {
|
||||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
const ADDR: &str = "::1";
|
||||||
|
let addr = ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(ADDR))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|addr| addr.addr),
|
||||||
|
Some(addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_listen_address_flag_dual_stack() {
|
||||||
|
const V4_ADDR: &str = "127.0.0.1";
|
||||||
|
const V6_ADDR: &str = "::1";
|
||||||
|
let ipv6_addr = V6_ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let ipv4_addr = V4_ADDR.parse::<Ipv4Addr>().unwrap();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V6_ADDR))
|
||||||
|
.flag("listen-address", Some(V4_ADDR))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|addr| addr.addr),
|
||||||
|
Some(ipv6_addr)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|addr| addr.addr),
|
||||||
|
Some(ipv4_addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn network_listen_address_flag_wrong_double_v4_value_config() {
|
||||||
|
// It's actually possible to listen over multiple sockets in libp2p over the same ip version.
|
||||||
|
// However this is not compatible with the single contactable address over each version in ENR.
|
||||||
|
// Because of this, it's important to test this is disallowed.
|
||||||
|
const V4_ADDR1: &str = "127.0.0.1";
|
||||||
|
const V4_ADDR2: &str = "0.0.0.0";
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V4_ADDR1))
|
||||||
|
.flag("listen-address", Some(V4_ADDR2))
|
||||||
|
.run_with_zero_port();
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn network_listen_address_flag_wrong_double_v6_value_config() {
|
||||||
|
// It's actually possible to listen over multiple sockets in libp2p over the same ip version.
|
||||||
|
// However this is not compatible with the single contactable address over each version in ENR.
|
||||||
|
// Because of this, it's important to test this is disallowed.
|
||||||
|
const V6_ADDR1: &str = "::3";
|
||||||
|
const V6_ADDR2: &str = "::1";
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V6_ADDR1))
|
||||||
|
.flag("listen-address", Some(V6_ADDR2))
|
||||||
|
.run_with_zero_port();
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_flag_over_ipv4() {
|
||||||
|
let port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port);
|
assert_eq!(
|
||||||
assert_eq!(config.network.discovery_port, port);
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.udp_port, listen_addr.tcp_port)),
|
||||||
|
Some((port, port))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_port_and_discovery_port_flags() {
|
fn network_port_flag_over_ipv6() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port1.to_string().as_str()))
|
.flag("listen-address", Some("::1"))
|
||||||
.flag("discovery-port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port1);
|
assert_eq!(
|
||||||
assert_eq!(config.network.discovery_port, port2);
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.udp_port, listen_addr.tcp_port)),
|
||||||
|
Some((port, port))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv4() {
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp4_port, udp4_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv6() {
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some("::1"))
|
||||||
|
.flag("port", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp6_port, udp6_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv4_and_ipv6() {
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some("::1"))
|
||||||
|
.flag("listen-address", Some("127.0.0.1"))
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.flag("port6", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port6", Some(udp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp4_port, udp4_port))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp6_port, udp6_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn disable_discovery_flag() {
|
fn disable_discovery_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
@ -986,7 +1137,6 @@ fn zero_ports_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, None);
|
|
||||||
assert_eq!(config.http_api.listen_port, 0);
|
assert_eq!(config.http_api.listen_port, 0);
|
||||||
assert_eq!(config.http_metrics.listen_port, 0);
|
assert_eq!(config.http_metrics.listen_port, 0);
|
||||||
});
|
});
|
||||||
@ -1003,67 +1153,171 @@ fn network_load_flag() {
|
|||||||
|
|
||||||
// Tests for ENR flags.
|
// Tests for ENR flags.
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_udp_port_flags() {
|
fn enr_udp_port_flag() {
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_udp4_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_tcp_port_flags() {
|
fn enr_tcp_port_flag() {
|
||||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
let port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_tcp4_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_match_flag() {
|
fn enr_udp6_port_flag() {
|
||||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
let port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
let port1 = unused_udp_port().expect("Unable to find unused port.");
|
CommandLineTest::new()
|
||||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
.flag("enr-udp6-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| assert_eq!(config.network.enr_udp6_port, Some(port)));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_tcp6_port_flag() {
|
||||||
|
let port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-tcp6-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| assert_eq!(config.network.enr_tcp6_port, Some(port)));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_match_flag_over_ipv4() {
|
||||||
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-match", None)
|
.flag("enr-match", None)
|
||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.flag("discovery-port", Some(port1.to_string().as_str()))
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.listen_address, addr);
|
assert_eq!(
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
config.network.listen_addrs().v4().map(|listen_addr| (
|
||||||
assert_eq!(config.network.discovery_port, port1);
|
listen_addr.addr,
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port1));
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((addr, udp4_port, tcp4_port))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(udp4_port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_address_flag() {
|
fn enr_match_flag_over_ipv6() {
|
||||||
let addr = "192.167.1.1".parse::<IpAddr>().unwrap();
|
const ADDR: &str = "::1";
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let addr = ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-match", None)
|
||||||
|
.flag("listen-address", Some(ADDR))
|
||||||
|
.flag("discovery-port", Some(udp6_port.to_string().as_str()))
|
||||||
|
.flag("port", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((addr, udp6_port, tcp6_port))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_address, (None, Some(addr)));
|
||||||
|
assert_eq!(config.network.enr_udp6_port, Some(udp6_port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_match_flag_over_ipv4_and_ipv6() {
|
||||||
|
const IPV6_ADDR: &str = "::1";
|
||||||
|
let ipv6_addr = IPV6_ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
const IPV4_ADDR: &str = "127.0.0.1";
|
||||||
|
let ipv4_addr = IPV4_ADDR.parse::<Ipv4Addr>().unwrap();
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-match", None)
|
||||||
|
.flag("listen-address", Some(IPV4_ADDR))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("listen-address", Some(IPV6_ADDR))
|
||||||
|
.flag("discovery-port6", Some(udp6_port.to_string().as_str()))
|
||||||
|
.flag("port6", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((ipv6_addr, udp6_port, tcp6_port))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((ipv4_addr, udp4_port, tcp4_port))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.enr_address,
|
||||||
|
(Some(ipv4_addr), Some(ipv6_addr))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_udp6_port, Some(udp6_port));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(udp4_port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_address_flag_with_ipv4() {
|
||||||
|
let addr = "192.167.1.1".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("192.167.1.1"))
|
.flag("enr-address", Some("192.167.1.1"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_address_flag_with_ipv6() {
|
||||||
|
let addr = "192.167.1.1".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-address", Some("192.167.1.1"))
|
||||||
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_address_dns_flag() {
|
fn enr_address_dns_flag() {
|
||||||
let addr = "127.0.0.1".parse::<IpAddr>().unwrap();
|
let addr = Ipv4Addr::LOCALHOST;
|
||||||
let ipv6addr = "::1".parse::<IpAddr>().unwrap();
|
let ipv6addr = Ipv6Addr::LOCALHOST;
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("localhost"))
|
.flag("enr-address", Some("localhost"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(
|
assert!(
|
||||||
config.network.enr_address == Some(addr)
|
config.network.enr_address.0 == Some(addr)
|
||||||
|| config.network.enr_address == Some(ipv6addr)
|
|| config.network.enr_address.1 == Some(ipv6addr)
|
||||||
);
|
);
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -1100,8 +1354,8 @@ fn http_address_ipv6_flag() {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn http_port_flag() {
|
fn http_port_flag() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-port", Some(port1.to_string().as_str()))
|
.flag("http-port", Some(port1.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port2.to_string().as_str()))
|
||||||
@ -1215,8 +1469,8 @@ fn metrics_address_ipv6_flag() {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn metrics_port_flag() {
|
fn metrics_port_flag() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-port", Some(port1.to_string().as_str()))
|
.flag("metrics-port", Some(port1.to_string().as_str()))
|
||||||
|
@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_udp_port;
|
use unused_port::unused_udp4_port;
|
||||||
|
|
||||||
const IP_ADDRESS: &str = "192.168.2.108";
|
const IP_ADDRESS: &str = "192.168.2.108";
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ fn enr_address_arg() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn port_flag() {
|
fn port_flag() {
|
||||||
let port = unused_udp_port().unwrap();
|
let port = unused_udp4_port().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run_with_ip()
|
.run_with_ip()
|
||||||
@ -122,7 +122,7 @@ fn boot_nodes_flag() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_port_flag() {
|
fn enr_port_flag() {
|
||||||
let port = unused_udp_port().unwrap();
|
let port = unused_udp4_port().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-port", Some(port.to_string().as_str()))
|
.flag("enr-port", Some(port.to_string().as_str()))
|
||||||
.run_with_ip()
|
.run_with_ip()
|
||||||
|
@ -3,7 +3,7 @@ use std::io::prelude::*;
|
|||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::process::{Child, Command, Stdio};
|
use std::process::{Child, Command, Stdio};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
use web3::{transports::Http, Transport, Web3};
|
use web3::{transports::Http, Transport, Web3};
|
||||||
|
|
||||||
/// How long we will wait for ganache to indicate that it is ready.
|
/// How long we will wait for ganache to indicate that it is ready.
|
||||||
@ -65,7 +65,7 @@ impl GanacheInstance {
|
|||||||
/// Start a new `ganache` process, waiting until it indicates that it is ready to accept
|
/// Start a new `ganache` process, waiting until it indicates that it is ready to accept
|
||||||
/// RPC connections.
|
/// RPC connections.
|
||||||
pub fn new(chain_id: u64) -> Result<Self, String> {
|
pub fn new(chain_id: u64) -> Result<Self, String> {
|
||||||
let port = unused_tcp_port()?;
|
let port = unused_tcp4_port()?;
|
||||||
let binary = match cfg!(windows) {
|
let binary = match cfg!(windows) {
|
||||||
true => "ganache.cmd",
|
true => "ganache.cmd",
|
||||||
false => "ganache",
|
false => "ganache",
|
||||||
@ -97,7 +97,7 @@ impl GanacheInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fork(&self) -> Result<Self, String> {
|
pub fn fork(&self) -> Result<Self, String> {
|
||||||
let port = unused_tcp_port()?;
|
let port = unused_tcp4_port()?;
|
||||||
let binary = match cfg!(windows) {
|
let binary = match cfg!(windows) {
|
||||||
true => "ganache.cmd",
|
true => "ganache.cmd",
|
||||||
false => "ganache",
|
false => "ganache",
|
||||||
|
@ -4,7 +4,7 @@ use sensitive_url::SensitiveUrl;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Child;
|
use std::process::Child;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
||||||
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
||||||
@ -50,8 +50,8 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|||||||
pub fn new(engine: E) -> Self {
|
pub fn new(engine: E) -> Self {
|
||||||
let datadir = E::init_datadir();
|
let datadir = E::init_datadir();
|
||||||
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
||||||
let http_port = unused_tcp_port().unwrap();
|
let http_port = unused_tcp4_port().unwrap();
|
||||||
let http_auth_port = unused_tcp_port().unwrap();
|
let http_auth_port = unused_tcp4_port().unwrap();
|
||||||
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
||||||
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
||||||
.expect("failed to instantiate ethers provider");
|
.expect("failed to instantiate ethers provider");
|
||||||
|
@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use std::{env, fs::File};
|
use std::{env, fs::File};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
const GETH_BRANCH: &str = "master";
|
const GETH_BRANCH: &str = "master";
|
||||||
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";
|
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";
|
||||||
@ -83,7 +83,7 @@ impl GenericExecutionEngine for GethEngine {
|
|||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
jwt_secret_path: PathBuf,
|
jwt_secret_path: PathBuf,
|
||||||
) -> Child {
|
) -> Child {
|
||||||
let network_port = unused_tcp_port().unwrap();
|
let network_port = unused_tcp4_port().unwrap();
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
Command::new(Self::binary_path())
|
||||||
.arg("--datadir")
|
.arg("--datadir")
|
||||||
|
@ -6,7 +6,7 @@ use std::fs::File;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
/// We've pinned the Nethermind version since our method of using the `master` branch to
|
/// We've pinned the Nethermind version since our method of using the `master` branch to
|
||||||
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
|
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
|
||||||
@ -88,7 +88,7 @@ impl GenericExecutionEngine for NethermindEngine {
|
|||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
jwt_secret_path: PathBuf,
|
jwt_secret_path: PathBuf,
|
||||||
) -> Child {
|
) -> Child {
|
||||||
let network_port = unused_tcp_port().unwrap();
|
let network_port = unused_tcp4_port().unwrap();
|
||||||
let genesis_json_path = datadir.path().join("genesis.json");
|
let genesis_json_path = datadir.path().join("genesis.json");
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
Command::new(Self::binary_path())
|
||||||
|
@ -89,8 +89,9 @@ pub fn testing_client_config() -> ClientConfig {
|
|||||||
let mut client_config = ClientConfig::default();
|
let mut client_config = ClientConfig::default();
|
||||||
|
|
||||||
// Setting ports to `0` means that the OS will choose some available port.
|
// Setting ports to `0` means that the OS will choose some available port.
|
||||||
client_config.network.libp2p_port = 0;
|
client_config
|
||||||
client_config.network.discovery_port = 0;
|
.network
|
||||||
|
.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 0, 0);
|
||||||
client_config.network.upnp_enabled = false;
|
client_config.network.upnp_enabled = false;
|
||||||
client_config.http_api.enabled = true;
|
client_config.http_api.enabled = true;
|
||||||
client_config.http_api.listen_port = 0;
|
client_config.http_api.listen_port = 0;
|
||||||
|
@ -13,7 +13,7 @@ use node_test_rig::{
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use types::{Epoch, EthSpec, MinimalEthSpec};
|
use types::{Epoch, EthSpec, MinimalEthSpec};
|
||||||
@ -149,7 +149,7 @@ pub fn run_eth1_sim(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
beacon_config.eth1.chain_id = Eth1Id::from(chain_id);
|
beacon_config.eth1.chain_id = Eth1Id::from(chain_id);
|
||||||
beacon_config.network.target_peers = node_count - 1;
|
beacon_config.network.target_peers = node_count - 1;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
if post_merge_sim {
|
if post_merge_sim {
|
||||||
let el_config = execution_layer::Config {
|
let el_config = execution_layer::Config {
|
||||||
|
@ -58,10 +58,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
context: RuntimeContext<E>,
|
context: RuntimeContext<E>,
|
||||||
mut beacon_config: ClientConfig,
|
mut beacon_config: ClientConfig,
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
beacon_config.network.discovery_port = BOOTNODE_PORT;
|
beacon_config.network.set_ipv4_listening_address(
|
||||||
beacon_config.network.libp2p_port = BOOTNODE_PORT;
|
std::net::Ipv4Addr::UNSPECIFIED,
|
||||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT);
|
BOOTNODE_PORT,
|
||||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT);
|
BOOTNODE_PORT,
|
||||||
|
);
|
||||||
|
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT);
|
||||||
|
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT);
|
||||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||||
|
|
||||||
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||||
@ -132,10 +135,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
.enr()
|
.enr()
|
||||||
.expect("bootnode must have a network"),
|
.expect("bootnode must have a network"),
|
||||||
);
|
);
|
||||||
beacon_config.network.discovery_port = BOOTNODE_PORT + count;
|
beacon_config.network.set_ipv4_listening_address(
|
||||||
beacon_config.network.libp2p_port = BOOTNODE_PORT + count;
|
std::net::Ipv4Addr::UNSPECIFIED,
|
||||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT + count);
|
BOOTNODE_PORT + count,
|
||||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT + count);
|
BOOTNODE_PORT + count,
|
||||||
|
);
|
||||||
|
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT + count);
|
||||||
|
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT + count);
|
||||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||||
}
|
}
|
||||||
if let Some(el_config) = &mut beacon_config.execution_layer {
|
if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||||
|
@ -7,7 +7,7 @@ use node_test_rig::{
|
|||||||
};
|
};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use types::{Epoch, EthSpec, MainnetEthSpec};
|
use types::{Epoch, EthSpec, MainnetEthSpec};
|
||||||
@ -91,7 +91,7 @@ pub fn run_no_eth1_sim(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
beacon_config.dummy_eth1_backend = true;
|
beacon_config.dummy_eth1_backend = true;
|
||||||
beacon_config.sync_eth1_chain = true;
|
beacon_config.sync_eth1_chain = true;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
let main_future = async {
|
let main_future = async {
|
||||||
let network = LocalNetwork::new(context.clone(), beacon_config.clone()).await?;
|
let network = LocalNetwork::new(context.clone(), beacon_config.clone()).await?;
|
||||||
|
@ -8,7 +8,7 @@ use node_test_rig::{
|
|||||||
};
|
};
|
||||||
use node_test_rig::{testing_validator_config, ClientConfig};
|
use node_test_rig::{testing_validator_config, ClientConfig};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use types::{Epoch, EthSpec};
|
use types::{Epoch, EthSpec};
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ fn syncing_sim(
|
|||||||
|
|
||||||
beacon_config.http_api.allow_sync_stalled = true;
|
beacon_config.http_api.allow_sync_stalled = true;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
// Generate the directories and keystores required for the validator clients.
|
// Generate the directories and keystores required for the validator clients.
|
||||||
let validator_indices = (0..num_validators).collect::<Vec<_>>();
|
let validator_indices = (0..num_validators).collect::<Vec<_>>();
|
||||||
|
Loading…
Reference in New Issue
Block a user