mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 18:04:18 +00:00
Merge branch 'unstable' into eip4844
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::listen_addr::{ListenAddr, ListenAddress};
|
||||
use crate::rpc::config::OutboundRateLimiterConfig;
|
||||
use crate::types::GossipKind;
|
||||
use crate::{Enr, PeerIdSerialized};
|
||||
@@ -12,6 +13,7 @@ use libp2p::gossipsub::{
|
||||
use libp2p::Multiaddr;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -57,24 +59,24 @@ pub struct Config {
|
||||
/// Data directory where node's keyfile is stored
|
||||
pub network_dir: PathBuf,
|
||||
|
||||
/// IP address to listen on.
|
||||
pub listen_address: std::net::IpAddr,
|
||||
|
||||
/// The TCP port that libp2p listens on.
|
||||
pub libp2p_port: u16,
|
||||
|
||||
/// UDP port that discovery listens on.
|
||||
pub discovery_port: u16,
|
||||
/// IP addresses to listen on.
|
||||
listen_addresses: ListenAddress,
|
||||
|
||||
/// The address to broadcast to peers about which address we are listening on. None indicates
|
||||
/// that no discovery address has been set in the CLI args.
|
||||
pub enr_address: Option<std::net::IpAddr>,
|
||||
pub enr_address: (Option<Ipv4Addr>, Option<Ipv6Addr>),
|
||||
|
||||
/// The udp port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp_port: Option<u16>,
|
||||
/// The udp4 port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp4_port: Option<u16>,
|
||||
|
||||
/// The tcp port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp_port: Option<u16>,
|
||||
/// The tcp4 port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp4_port: Option<u16>,
|
||||
|
||||
/// The udp6 port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp6_port: Option<u16>,
|
||||
|
||||
/// The tcp6 port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp6_port: Option<u16>,
|
||||
|
||||
/// Target number of connected peers.
|
||||
pub target_peers: usize,
|
||||
@@ -139,6 +141,105 @@ pub struct Config {
|
||||
pub outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Sets the listening address to use an ipv4 address. The discv5 ip_mode and table filter are
|
||||
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||
/// reachable.
|
||||
pub fn set_ipv4_listening_address(&mut self, addr: Ipv4Addr, tcp_port: u16, udp_port: u16) {
|
||||
self.listen_addresses = ListenAddress::V4(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
});
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip4;
|
||||
self.discv5_config.table_filter = |enr| enr.ip4().as_ref().map_or(false, is_global_ipv4)
|
||||
}
|
||||
|
||||
/// Sets the listening address to use an ipv6 address. The discv5 ip_mode and table filter is
|
||||
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||
/// reachable.
|
||||
pub fn set_ipv6_listening_address(&mut self, addr: Ipv6Addr, tcp_port: u16, udp_port: u16) {
|
||||
self.listen_addresses = ListenAddress::V6(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
});
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||
enable_mapped_addresses: false,
|
||||
};
|
||||
self.discv5_config.table_filter = |enr| enr.ip6().as_ref().map_or(false, is_global_ipv6)
|
||||
}
|
||||
|
||||
/// Sets the listening address to use both an ipv4 and ipv6 address. The discv5 ip_mode and
|
||||
/// table filter is adjusted accordingly to ensure addresses that are present in the enr are
|
||||
/// globally reachable.
|
||||
pub fn set_ipv4_ipv6_listening_addresses(
|
||||
&mut self,
|
||||
v4_addr: Ipv4Addr,
|
||||
tcp4_port: u16,
|
||||
udp4_port: u16,
|
||||
v6_addr: Ipv6Addr,
|
||||
tcp6_port: u16,
|
||||
udp6_port: u16,
|
||||
) {
|
||||
self.listen_addresses = ListenAddress::DualStack(
|
||||
ListenAddr {
|
||||
addr: v4_addr,
|
||||
udp_port: udp4_port,
|
||||
tcp_port: tcp4_port,
|
||||
},
|
||||
ListenAddr {
|
||||
addr: v6_addr,
|
||||
udp_port: udp6_port,
|
||||
tcp_port: tcp6_port,
|
||||
},
|
||||
);
|
||||
|
||||
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||
enable_mapped_addresses: true,
|
||||
};
|
||||
self.discv5_config.table_filter = |enr| match (&enr.ip4(), &enr.ip6()) {
|
||||
(None, None) => false,
|
||||
(None, Some(ip6)) => is_global_ipv6(ip6),
|
||||
(Some(ip4), None) => is_global_ipv4(ip4),
|
||||
(Some(ip4), Some(ip6)) => is_global_ipv4(ip4) && is_global_ipv6(ip6),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_listening_addr(&mut self, listen_addr: ListenAddress) {
|
||||
match listen_addr {
|
||||
ListenAddress::V4(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
}) => self.set_ipv4_listening_address(addr, tcp_port, udp_port),
|
||||
ListenAddress::V6(ListenAddr {
|
||||
addr,
|
||||
udp_port,
|
||||
tcp_port,
|
||||
}) => self.set_ipv6_listening_address(addr, tcp_port, udp_port),
|
||||
ListenAddress::DualStack(
|
||||
ListenAddr {
|
||||
addr: ip4addr,
|
||||
udp_port: udp4_port,
|
||||
tcp_port: tcp4_port,
|
||||
},
|
||||
ListenAddr {
|
||||
addr: ip6addr,
|
||||
udp_port: udp6_port,
|
||||
tcp_port: tcp6_port,
|
||||
},
|
||||
) => self.set_ipv4_ipv6_listening_addresses(
|
||||
ip4addr, tcp4_port, udp4_port, ip6addr, tcp6_port, udp6_port,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn listen_addrs(&self) -> &ListenAddress {
|
||||
&self.listen_addresses
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
/// Generate a default network configuration.
|
||||
fn default() -> Self {
|
||||
@@ -183,7 +284,7 @@ impl Default for Config {
|
||||
.filter_rate_limiter(filter_rate_limiter)
|
||||
.filter_max_bans_per_ip(Some(5))
|
||||
.filter_max_nodes_per_ip(Some(10))
|
||||
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global(&ip))) // Filter non-global IPs
|
||||
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global_ipv4(&ip))) // Filter non-global IPs
|
||||
.ban_duration(Some(Duration::from_secs(3600)))
|
||||
.ping_interval(Duration::from_secs(300))
|
||||
.build();
|
||||
@@ -191,12 +292,16 @@ impl Default for Config {
|
||||
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
||||
Config {
|
||||
network_dir,
|
||||
listen_address: "0.0.0.0".parse().expect("valid ip address"),
|
||||
libp2p_port: 9000,
|
||||
discovery_port: 9000,
|
||||
enr_address: None,
|
||||
enr_udp_port: None,
|
||||
enr_tcp_port: None,
|
||||
listen_addresses: ListenAddress::V4(ListenAddr {
|
||||
addr: Ipv4Addr::UNSPECIFIED,
|
||||
udp_port: 9000,
|
||||
tcp_port: 9000,
|
||||
}),
|
||||
enr_address: (None, None),
|
||||
enr_udp4_port: None,
|
||||
enr_tcp4_port: None,
|
||||
enr_udp6_port: None,
|
||||
enr_tcp6_port: None,
|
||||
target_peers: 50,
|
||||
gs_config,
|
||||
discv5_config,
|
||||
@@ -363,7 +468,7 @@ pub fn gossipsub_config(network_load: u8, fork_context: Arc<ForkContext>) -> Gos
|
||||
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
|
||||
/// function is not yet stable on IpAddr.
|
||||
#[allow(clippy::nonminimal_bool)]
|
||||
fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
||||
fn is_global_ipv4(addr: &Ipv4Addr) -> bool {
|
||||
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
|
||||
// globally routable addresses in the 192.0.0.0/24 range.
|
||||
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
||||
@@ -384,3 +489,60 @@ fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
||||
// Make sure the address is not in 0.0.0.0/8
|
||||
&& addr.octets()[0] != 0
|
||||
}
|
||||
|
||||
/// NOTE: Docs taken from https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_global
|
||||
///
|
||||
/// Returns true if the address appears to be globally reachable as specified by the IANA IPv6
|
||||
/// Special-Purpose Address Registry. Whether or not an address is practically reachable will
|
||||
/// depend on your network configuration.
|
||||
///
|
||||
/// Most IPv6 addresses are globally reachable; unless they are specifically defined as not
|
||||
/// globally reachable.
|
||||
///
|
||||
/// Non-exhaustive list of notable addresses that are not globally reachable:
|
||||
///
|
||||
/// - The unspecified address (is_unspecified)
|
||||
/// - The loopback address (is_loopback)
|
||||
/// - IPv4-mapped addresses
|
||||
/// - Addresses reserved for benchmarking
|
||||
/// - Addresses reserved for documentation (is_documentation)
|
||||
/// - Unique local addresses (is_unique_local)
|
||||
/// - Unicast addresses with link-local scope (is_unicast_link_local)
|
||||
// TODO: replace with [`Ipv6Addr::is_global`] once
|
||||
// [Ip](https://github.com/rust-lang/rust/issues/27709) is stable.
|
||||
pub const fn is_global_ipv6(addr: &Ipv6Addr) -> bool {
|
||||
const fn is_documentation(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] == 0x2001) && (addr.segments()[1] == 0xdb8)
|
||||
}
|
||||
const fn is_unique_local(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] & 0xfe00) == 0xfc00
|
||||
}
|
||||
const fn is_unicast_link_local(addr: &Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] & 0xffc0) == 0xfe80
|
||||
}
|
||||
!(addr.is_unspecified()
|
||||
|| addr.is_loopback()
|
||||
// IPv4-mapped Address (`::ffff:0:0/96`)
|
||||
|| matches!(addr.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
|
||||
// IPv4-IPv6 Translat. (`64:ff9b:1::/48`)
|
||||
|| matches!(addr.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
|
||||
// Discard-Only Address Block (`100::/64`)
|
||||
|| matches!(addr.segments(), [0x100, 0, 0, 0, _, _, _, _])
|
||||
// IETF Protocol Assignments (`2001::/23`)
|
||||
|| (matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
|
||||
&& !(
|
||||
// Port Control Protocol Anycast (`2001:1::1`)
|
||||
u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
|
||||
// Traversal Using Relays around NAT Anycast (`2001:1::2`)
|
||||
|| u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
|
||||
// AMT (`2001:3::/32`)
|
||||
|| matches!(addr.segments(), [0x2001, 3, _, _, _, _, _, _])
|
||||
// AS112-v6 (`2001:4:112::/48`)
|
||||
|| matches!(addr.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
|
||||
// ORCHIDv2 (`2001:20::/28`)
|
||||
|| matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
|
||||
))
|
||||
|| is_documentation(addr)
|
||||
|| is_unique_local(addr)
|
||||
|| is_unicast_link_local(addr))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user