Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broadcast external IP from NAT in enode record #10274

Merged
merged 18 commits into from
Oct 10, 2024
Merged
3 changes: 3 additions & 0 deletions book/cli/reth/debug/execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/debug/in-memory-merkle.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/debug/merkle.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/debug/replay-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/p2p.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/stage/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/stage/unwind.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ Networking:
--enable-discv5-discovery
Enable Discv5 discovery

--disable-nat
Disable Nat discovery

--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4

Expand Down
22 changes: 21 additions & 1 deletion crates/net/network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ pub struct NetworkConfig<C> {
pub tx_gossip_disabled: bool,
/// How to instantiate transactions manager.
pub transactions_manager_config: TransactionsManagerConfig,
/// The NAT resolver for external IP
pub nat: Option<NatResolver>,
}

// === impl NetworkConfig ===
Expand Down Expand Up @@ -188,6 +190,8 @@ pub struct NetworkConfigBuilder {
block_import: Option<Box<dyn BlockImport>>,
/// How to instantiate transactions manager.
transactions_manager_config: TransactionsManagerConfig,
/// The NAT resolver for external IP
nat: Option<NatResolver>,
}

// === impl NetworkConfigBuilder ===
Expand Down Expand Up @@ -220,6 +224,7 @@ impl NetworkConfigBuilder {
tx_gossip_disabled: false,
block_import: None,
transactions_manager_config: Default::default(),
nat: None,
}
}

Expand Down Expand Up @@ -355,6 +360,7 @@ impl NetworkConfigBuilder {
self.discovery_v4_builder
.get_or_insert_with(Discv4Config::builder)
.external_ip_resolver(Some(resolver));
self.nat = Some(resolver);
self
}

Expand Down Expand Up @@ -403,9 +409,15 @@ impl NetworkConfigBuilder {
self
}

// Disable nat
pub const fn disable_nat(mut self) -> Self {
self.nat = None;
self
}

/// Disables all discovery.
pub fn disable_discovery(self) -> Self {
self.disable_discv4_discovery().disable_dns_discovery()
self.disable_discv4_discovery().disable_dns_discovery().disable_nat()
}

/// Disables all discovery if the given condition is true.
Expand Down Expand Up @@ -467,6 +479,12 @@ impl NetworkConfigBuilder {
self.build(Default::default())
}

/// Sets the NAT resolver for external IP.
pub const fn add_nat(mut self, nat: Option<NatResolver>) -> Self {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this mainly so that the unit test can be written more conveniently, would love to know if there's a better way

self.nat = nat;
self
}

/// Consumes the type and creates the actual [`NetworkConfig`]
/// for the given client type that can interact with the chain.
///
Expand Down Expand Up @@ -494,6 +512,7 @@ impl NetworkConfigBuilder {
tx_gossip_disabled,
block_import,
transactions_manager_config,
nat,
} = self;

discovery_v5_builder = discovery_v5_builder.map(|mut builder| {
Expand Down Expand Up @@ -557,6 +576,7 @@ impl NetworkConfigBuilder {
fork_filter,
tx_gossip_disabled,
transactions_manager_config,
nat,
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/net/network/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ impl NetworkManager {
extra_protocols,
tx_gossip_disabled,
transactions_manager_config: _,
nat,
} = config;

let peers_manager = PeersManager::new(peers_config);
Expand Down Expand Up @@ -269,6 +270,7 @@ impl NetworkManager {
discv4,
discv5,
event_sender.clone(),
nat,
);

Ok(Self {
Expand Down
18 changes: 15 additions & 3 deletions crates/net/network/src/network.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
net::SocketAddr,
net::{IpAddr, SocketAddr},
sync::{
atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
Arc,
Expand All @@ -8,7 +8,7 @@ use std::{

use enr::Enr;
use parking_lot::Mutex;
use reth_discv4::Discv4;
use reth_discv4::{Discv4, NatResolver};
use reth_discv5::Discv5;
use reth_eth_wire::{DisconnectReason, NewBlock, NewPooledTransactionHashes, SharedTransactions};
use reth_network_api::{
Expand Down Expand Up @@ -64,6 +64,7 @@ impl NetworkHandle {
discv4: Option<Discv4>,
discv5: Option<Discv5>,
event_sender: EventSender<NetworkEvent>,
nat: Option<NatResolver>,
) -> Self {
let inner = NetworkInner {
num_active_peers,
Expand All @@ -80,6 +81,7 @@ impl NetworkHandle {
discv4,
discv5,
event_sender,
nat,
};
Self { inner: Arc::new(inner) }
}
Expand Down Expand Up @@ -218,7 +220,15 @@ impl PeersInfo for NetworkHandle {
let id = *self.peer_id();
let mut socket_addr = *self.inner.listener_address.lock();

if socket_addr.ip().is_unspecified() {
let external_ip: Option<IpAddr> = self.inner.nat.and_then(|nat| match nat {
NatResolver::ExternalIp(ip) => Some(ip),
_ => None,
});

// if able to resolve external ip, use it instead
if let Some(ip) = external_ip {
socket_addr.set_ip(ip)
} else if socket_addr.ip().is_unspecified() {
// zero address is invalid
if socket_addr.ip().is_ipv4() {
socket_addr.set_ip(std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST));
Expand Down Expand Up @@ -431,6 +441,8 @@ struct NetworkInner {
discv5: Option<Discv5>,
/// Sender for high level network events.
event_sender: EventSender<NetworkEvent>,
/// The NAT resolver
nat: Option<NatResolver>,
}

/// Provides access to modify the network's additional protocol handlers.
Expand Down
35 changes: 33 additions & 2 deletions crates/net/network/tests/it/startup.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
io,
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4},
};

use reth_discv4::Discv4Config;
use reth_discv4::{Discv4Config, NatResolver};
use reth_network::{
error::{NetworkError, ServiceKind},
Discovery, NetworkConfigBuilder, NetworkManager,
Expand Down Expand Up @@ -104,3 +104,34 @@ async fn test_tcp_port_node_record_discovery() {
assert_eq!(record.tcp_port, local_addr.port());
assert_ne!(record.udp_port, 0);
}

// <https://github.com/paradigmxyz/reth/issues/8851>
#[tokio::test(flavor = "multi_thread")]
async fn test_node_record_address_with_nat() {
let secret_key = SecretKey::new(&mut rand::thread_rng());
let config = NetworkConfigBuilder::new(secret_key)
.add_nat(Some(NatResolver::ExternalIp("10.1.1.1".parse().unwrap())))
.disable_discv4_discovery()
.disable_dns_discovery()
.build_with_noop_provider();

let network = NetworkManager::new(config).await.unwrap();
let record = network.handle().local_node_record();

assert_eq!(record.address, IpAddr::V4(Ipv4Addr::new(10, 1, 1, 1)));
}

// <https://github.com/paradigmxyz/reth/issues/8851>
#[tokio::test(flavor = "multi_thread")]
async fn test_node_record_address_with_nat_disable_discovery() {
let secret_key = SecretKey::new(&mut rand::thread_rng());
let config = NetworkConfigBuilder::new(secret_key)
.add_nat(Some(NatResolver::ExternalIp("10.1.1.1".parse().unwrap())))
.disable_discovery()
.build_with_noop_provider();

let network = NetworkManager::new(config).await.unwrap();
let record = network.handle().local_node_record();

assert_eq!(record.address, IpAddr::V4(std::net::Ipv4Addr::LOCALHOST));
}
11 changes: 10 additions & 1 deletion crates/node/core/src/args/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl NetworkArgs {

DEFAULT_DISCOVERY_ADDR
}
}
};
}

self.addr
Expand Down Expand Up @@ -358,6 +358,10 @@ pub struct DiscoveryArgs {
#[arg(long, conflicts_with = "disable_discovery")]
pub enable_discv5_discovery: bool,

/// Disable Nat discovery.
#[arg(long, conflicts_with = "disable_discovery")]
pub disable_nat: bool,

/// The UDP address to use for devp2p peer discovery version 4.
#[arg(id = "discovery.addr", long = "discovery.addr", value_name = "DISCOVERY_ADDR", default_value_t = DEFAULT_DISCOVERY_ADDR)]
pub addr: IpAddr,
Expand Down Expand Up @@ -421,6 +425,10 @@ impl DiscoveryArgs {
network_config_builder = network_config_builder.disable_discv4_discovery();
}

if self.disable_discovery || self.disable_nat {
network_config_builder = network_config_builder.disable_nat();
}

if !self.disable_discovery && self.enable_discv5_discovery {
network_config_builder = network_config_builder
.discovery_v5(self.discovery_v5_builder(rlpx_tcp_socket, boot_nodes));
Expand Down Expand Up @@ -497,6 +505,7 @@ impl Default for DiscoveryArgs {
disable_dns_discovery: false,
disable_discv4_discovery: false,
enable_discv5_discovery: false,
disable_nat: false,
addr: DEFAULT_DISCOVERY_ADDR,
port: DEFAULT_DISCOVERY_PORT,
discv5_addr: None,
Expand Down
Loading