diff --git a/cli/src/commands/node/mod.rs b/cli/src/commands/node/mod.rs index 436e600f6..1e78d5af5 100644 --- a/cli/src/commands/node/mod.rs +++ b/cli/src/commands/node/mod.rs @@ -44,6 +44,10 @@ pub struct Node { #[arg(env = "MINA_LIBP2P_PASS")] pub libp2p_password: Option, + /// List of external addresses at which this node is accessible + #[arg(long)] + pub libp2p_external_ip: Vec, + /// Http port to listen on #[arg(long, short, env, default_value = "3000")] pub port: u16, @@ -194,6 +198,12 @@ impl Node { node_builder.p2p_libp2p_port(self.libp2p_port); + node_builder.external_addrs( + self.libp2p_external_ip + .into_iter() + .filter_map(|s| s.parse().ok()), + ); + self.seed.then(|| node_builder.p2p_seed_node()); self.no_peers_discovery .then(|| node_builder.p2p_no_discovery()); diff --git a/node/native/src/node/builder.rs b/node/native/src/node/builder.rs index 2f26611d8..f8400cd91 100644 --- a/node/native/src/node/builder.rs +++ b/node/native/src/node/builder.rs @@ -1,6 +1,7 @@ use std::{ fs::File, io::{BufRead, BufReader, Read}, + net::IpAddr, path::Path, sync::Arc, time::Duration, @@ -40,6 +41,7 @@ pub struct NodeBuilder { p2p_no_discovery: bool, p2p_is_started: bool, initial_peers: Vec, + external_addrs: Vec, block_producer: Option, snarker: Option, service: NodeServiceBuilder, @@ -73,6 +75,7 @@ impl NodeBuilder { p2p_no_discovery: false, p2p_is_started: false, initial_peers: Vec::new(), + external_addrs: Vec::new(), block_producer: None, snarker: None, service: NodeServiceBuilder::new(rng_seed), @@ -121,6 +124,11 @@ impl NodeBuilder { self } + pub fn external_addrs(&mut self, v: impl Iterator) -> &mut Self { + self.external_addrs.extend(v); + self + } + /// Extend p2p initial peers from file. pub fn initial_peers_from_file(&mut self, path: impl AsRef) -> anyhow::Result<&mut Self> { peers_from_reader( @@ -282,6 +290,8 @@ impl NodeBuilder { }) .collect(); + let external_addrs = self.external_addrs; + let srs = self.verifier_srs.unwrap_or_else(get_srs); let block_verifier_index = self .block_verifier_index @@ -311,6 +321,7 @@ impl NodeBuilder { listen_port: self.http_port, identity_pub_key: p2p_sec_key.public_key(), initial_peers, + external_addrs, ask_initial_peers_interval: Duration::from_secs(3600), enabled_channels: ChannelId::iter_all().collect(), peer_discovery: !self.p2p_no_discovery, diff --git a/node/testing/src/cluster/mod.rs b/node/testing/src/cluster/mod.rs index c2073d856..8a39c9555 100644 --- a/node/testing/src/cluster/mod.rs +++ b/node/testing/src/cluster/mod.rs @@ -281,6 +281,7 @@ impl Cluster { listen_port: Some(http_port), identity_pub_key: p2p_sec_key.public_key(), initial_peers, + external_addrs: vec![], ask_initial_peers_interval: testing_config.ask_initial_peers_interval, enabled_channels: ChannelId::iter_all().collect(), peer_discovery: true, diff --git a/node/web/src/node/builder.rs b/node/web/src/node/builder.rs index 1d851f646..576724e24 100644 --- a/node/web/src/node/builder.rs +++ b/node/web/src/node/builder.rs @@ -230,6 +230,7 @@ impl NodeBuilder { listen_port: None, identity_pub_key: p2p_sec_key.public_key(), initial_peers, + external_addrs: vec![], ask_initial_peers_interval: Duration::from_secs(3600), enabled_channels: ChannelId::iter_all().collect(), peer_discovery: !self.p2p_no_discovery, diff --git a/p2p/src/network/identify/stream_effectful/p2p_network_identify_stream_effectful_effects.rs b/p2p/src/network/identify/stream_effectful/p2p_network_identify_stream_effectful_effects.rs index f7360c1ec..177046a06 100644 --- a/p2p/src/network/identify/stream_effectful/p2p_network_identify_stream_effectful_effects.rs +++ b/p2p/src/network/identify/stream_effectful/p2p_network_identify_stream_effectful_effects.rs @@ -49,7 +49,15 @@ impl P2pNetworkIdentifyStreamEffectfulAction { peer_id, stream_id, } => { - let mut listen_addrs = Vec::new(); + let config = &store.state().config; + let ips = &config.external_addrs; + let port = config.libp2p_port.unwrap_or(8302); + + let mut listen_addrs = ips + .iter() + .map(|ip| Multiaddr::from(*ip).with(multiaddr::Protocol::Tcp(port))) + .collect::>(); + for addr in store .state() .network diff --git a/p2p/src/p2p_config.rs b/p2p/src/p2p_config.rs index ed1cc4c93..9a425a8b7 100644 --- a/p2p/src/p2p_config.rs +++ b/p2p/src/p2p_config.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeSet, time::Duration}; +use std::{collections::BTreeSet, net::IpAddr, time::Duration}; use serde::{Deserialize, Serialize}; @@ -22,6 +22,8 @@ pub struct P2pConfig { pub identity_pub_key: PublicKey, /// A list addresses of seed nodes. pub initial_peers: Vec, + /// External addresses + pub external_addrs: Vec, /// The time interval that must elapse before the next peer discovery request. /// The node periodically polls peers for their connections to keep our list up to date. diff --git a/p2p/testing/src/cluster.rs b/p2p/testing/src/cluster.rs index 8440a26f2..671f55887 100644 --- a/p2p/testing/src/cluster.rs +++ b/p2p/testing/src/cluster.rs @@ -354,6 +354,7 @@ impl Cluster { listen_port: Some(listen_port), identity_pub_key: secret_key.public_key(), initial_peers, + external_addrs: vec![], ask_initial_peers_interval: Duration::from_secs(5), enabled_channels: p2p::channels::ChannelId::for_libp2p().collect(), peer_discovery: config.discovery,