From 7e04ae857ce720d6265451f201d0f91a22e4fa68 Mon Sep 17 00:00:00 2001 From: Shahak Shama Date: Thu, 15 Aug 2024 09:58:57 +0300 Subject: [PATCH] feat(network): hardcode the external address of the node --- config/papyrus/default_config.json | 10 +++++++ .../papyrus_network/src/e2e_broadcast_test.rs | 2 +- crates/papyrus_network/src/lib.rs | 11 ++++++++ .../src/network_manager/mod.rs | 26 ++++++++++++++++--- .../src/network_manager/swarm_trait.rs | 3 ++- .../src/network_manager/test.rs | 8 +++--- ...fig__config_test__dump_default_config.snap | 10 +++++++ 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/config/papyrus/default_config.json b/config/papyrus/default_config.json index 81f897e70d..9a0f2ddcb0 100644 --- a/config/papyrus/default_config.json +++ b/config/papyrus/default_config.json @@ -179,6 +179,16 @@ "pointer_target": "chain_id", "privacy": "Public" }, + "network.hardcoded_external_multiaddr": { + "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", + "privacy": "Public", + "value": "" + }, + "network.hardcoded_external_multiaddr.#is_none": { + "description": "Flag for an optional field.", + "privacy": "TemporaryValue", + "value": true + }, "network.idle_connection_timeout": { "description": "Amount of time in seconds that a connection with no active sessions will stay alive.", "privacy": "Public", diff --git a/crates/papyrus_network/src/e2e_broadcast_test.rs b/crates/papyrus_network/src/e2e_broadcast_test.rs index 5895427e65..9eabf83d50 100644 --- a/crates/papyrus_network/src/e2e_broadcast_test.rs +++ b/crates/papyrus_network/src/e2e_broadcast_test.rs @@ -44,7 +44,7 @@ async fn create_swarm(bootstrap_peer_multiaddr: Option) -> Swarm, ) -> GenericNetworkManager> { - GenericNetworkManager::generic_new(swarm) + GenericNetworkManager::generic_new(swarm, None) } const BUFFER_SIZE: usize = 100; diff --git a/crates/papyrus_network/src/lib.rs b/crates/papyrus_network/src/lib.rs index 696118710e..0ce213ba9b 100644 --- a/crates/papyrus_network/src/lib.rs +++ b/crates/papyrus_network/src/lib.rs @@ -44,6 +44,7 @@ pub struct NetworkConfig { #[validate(custom = "validate_vec_u256")] #[serde(deserialize_with = "deserialize_optional_vec_u8")] pub(crate) secret_key: Option>, + pub hardcoded_external_multiaddr: Option, pub chain_id: ChainId, } @@ -96,6 +97,15 @@ impl SerializeConfig for NetworkConfig { will be used.", ParamPrivacyInput::Private, )]); + config.extend(ser_optional_param( + &self.bootstrap_peer_multiaddr, + Multiaddr::empty(), + "hardcoded_external_multiaddr", + "The external address other peers see this node. If this is set, the node will not \ + try to find out which addresses it has and will write this address as external \ + instead", + ParamPrivacyInput::Public, + )); config } } @@ -109,6 +119,7 @@ impl Default for NetworkConfig { idle_connection_timeout: Duration::from_secs(120), bootstrap_peer_multiaddr: None, secret_key: None, + hardcoded_external_multiaddr: None, chain_id: ChainId::Mainnet, } } diff --git a/crates/papyrus_network/src/network_manager/mod.rs b/crates/papyrus_network/src/network_manager/mod.rs index a71c8880c7..b6e62077e6 100644 --- a/crates/papyrus_network/src/network_manager/mod.rs +++ b/crates/papyrus_network/src/network_manager/mod.rs @@ -52,6 +52,7 @@ pub struct GenericNetworkManager { messages_to_broadcast_receivers: StreamHashMap>, broadcasted_messages_senders: HashMap>, reported_peer_receivers: FuturesUnordered>>, + hardcoded_external_multiaddr: Option, // Fields for metrics num_active_inbound_sessions: usize, num_active_outbound_sessions: usize, @@ -74,10 +75,18 @@ impl GenericNetworkManager { } } - pub(crate) fn generic_new(swarm: SwarmT) -> Self { + // TODO(shahak): remove the hardcoded_external_multiaddr arg once we manage external addresses + // in a behaviour. + pub(crate) fn generic_new( + mut swarm: SwarmT, + hardcoded_external_multiaddr: Option, + ) -> Self { gauge!(papyrus_metrics::PAPYRUS_NUM_CONNECTED_PEERS, 0f64); let reported_peer_receivers = FuturesUnordered::new(); reported_peer_receivers.push(futures::future::pending().boxed()); + if let Some(address) = hardcoded_external_multiaddr.clone() { + swarm.add_external_address(address); + } Self { swarm, inbound_protocol_to_buffer_size: HashMap::new(), @@ -89,6 +98,7 @@ impl GenericNetworkManager { messages_to_broadcast_receivers: StreamHashMap::new(HashMap::new()), broadcasted_messages_senders: HashMap::new(), reported_peer_receivers, + hardcoded_external_multiaddr, num_active_inbound_sessions: 0, num_active_outbound_sessions: 0, } @@ -258,13 +268,14 @@ impl GenericNetworkManager { } SwarmEvent::NewListenAddr { address, .. } => { // TODO(shahak): Find a better way to filter private addresses. - if !is_localhost(&address) { + if !is_localhost(&address) && self.hardcoded_external_multiaddr.is_none() { self.swarm.add_external_address(address); } } SwarmEvent::IncomingConnection { .. } | SwarmEvent::Dialing { .. } - | SwarmEvent::NewExternalAddrCandidate { .. } => {} + | SwarmEvent::NewExternalAddrCandidate { .. } + | SwarmEvent::NewExternalAddrOfPeer { .. } => {} _ => { error!("Unexpected event {event:?}"); } @@ -556,6 +567,7 @@ impl NetworkManager { session_timeout, idle_connection_timeout, bootstrap_peer_multiaddr, + hardcoded_external_multiaddr, secret_key, chain_id, } = config; @@ -565,6 +577,7 @@ impl NetworkManager { // format!("/ip4/0.0.0.0/udp/{quic_port}/quic-v1"), format!("/ip4/0.0.0.0/tcp/{tcp_port}"), ]; + let swarm = build_swarm(listen_addresses, idle_connection_timeout, secret_key, |key| { mixed_behaviour::MixedBehaviour::new( key, @@ -573,7 +586,12 @@ impl NetworkManager { chain_id, ) }); - Self::generic_new(swarm) + let hardcoded_external_multiaddr = hardcoded_external_multiaddr.map(|address| { + address.with_p2p(*swarm.local_peer_id()).expect( + "hardcoded_external_multiaddr has a peer id different than the local peer id", + ) + }); + Self::generic_new(swarm, hardcoded_external_multiaddr) } pub fn get_local_peer_id(&self) -> String { diff --git a/crates/papyrus_network/src/network_manager/swarm_trait.rs b/crates/papyrus_network/src/network_manager/swarm_trait.rs index 270154f962..fde1e0e713 100644 --- a/crates/papyrus_network/src/network_manager/swarm_trait.rs +++ b/crates/papyrus_network/src/network_manager/swarm_trait.rs @@ -3,7 +3,7 @@ use libp2p::gossipsub::{SubscriptionError, TopicHash}; use libp2p::swarm::dial_opts::DialOpts; use libp2p::swarm::{DialError, NetworkBehaviour, SwarmEvent}; use libp2p::{Multiaddr, PeerId, StreamProtocol, Swarm}; -use tracing::error; +use tracing::{error, info}; use crate::gossipsub_impl::Topic; use crate::mixed_behaviour; @@ -102,6 +102,7 @@ impl SwarmTrait for Swarm { } fn add_external_address(&mut self, address: Multiaddr) { + info!("Found new external address of this node: {address:?}"); self.add_external_address(address); } diff --git a/crates/papyrus_network/src/network_manager/test.rs b/crates/papyrus_network/src/network_manager/test.rs index a2b8851836..c4ecb9519f 100644 --- a/crates/papyrus_network/src/network_manager/test.rs +++ b/crates/papyrus_network/src/network_manager/test.rs @@ -217,7 +217,7 @@ async fn register_sqmr_protocol_client_and_use_channels() { mock_swarm.first_polled_event_notifier = Some(event_notifier); // network manager to register subscriber - let mut network_manager = GenericNetworkManager::generic_new(mock_swarm); + let mut network_manager = GenericNetworkManager::generic_new(mock_swarm, None); // register subscriber and send payload let mut payload_sender = network_manager.register_sqmr_protocol_client::, Vec>( @@ -279,7 +279,7 @@ async fn process_incoming_query() { let get_responses_fut = mock_swarm.get_responses_sent_to_inbound_session(inbound_session_id); let mut get_supported_inbound_protocol_fut = mock_swarm.get_supported_inbound_protocol(); - let mut network_manager = GenericNetworkManager::generic_new(mock_swarm); + let mut network_manager = GenericNetworkManager::generic_new(mock_swarm, None); let mut inbound_payload_receiver = network_manager .register_sqmr_protocol_server::, Vec>(protocol.to_string(), BUFFER_SIZE); @@ -315,7 +315,7 @@ async fn broadcast_message() { let mut mock_swarm = MockSwarm::default(); let mut messages_we_broadcasted_stream = mock_swarm.stream_messages_we_broadcasted(); - let mut network_manager = GenericNetworkManager::generic_new(mock_swarm); + let mut network_manager = GenericNetworkManager::generic_new(mock_swarm, None); let mut messages_to_broadcast_sender = network_manager .register_broadcast_topic(topic.clone(), BUFFER_SIZE) @@ -351,7 +351,7 @@ async fn receive_broadcasted_message_and_report_it() { ))); let mut reported_peer_receiver = mock_swarm.get_reported_peers_stream(); - let mut network_manager = GenericNetworkManager::generic_new(mock_swarm); + let mut network_manager = GenericNetworkManager::generic_new(mock_swarm, None); let mut broadcasted_messages_receiver = network_manager .register_broadcast_topic::(topic.clone(), BUFFER_SIZE) diff --git a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap index 446e56caa8..b4a60c52ca 100644 --- a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap +++ b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap @@ -203,6 +203,16 @@ expression: dumped_default_config "value": "SN_MAIN", "privacy": "Public" }, + "network.hardcoded_external_multiaddr": { + "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", + "value": "", + "privacy": "Public" + }, + "network.hardcoded_external_multiaddr.#is_none": { + "description": "Flag for an optional field.", + "value": true, + "privacy": "TemporaryValue" + }, "network.idle_connection_timeout": { "description": "Amount of time in seconds that a connection with no active sessions will stay alive.", "value": {