From 4a4ca82a9a6810a9fe26456d5f7e336eb8d3c923 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Wed, 6 Nov 2024 18:26:27 +0200 Subject: [PATCH 1/6] wallet connectivity more logging persist changes to peer_manager in the watch updates to config files --- base_layer/p2p/src/config.rs | 2 ++ .../wallet/src/connectivity_service/service.rs | 17 +++++++++++------ common/config/presets/c_base_node_c.toml | 7 ++++++- common/config/presets/d_console_wallet.toml | 7 ++++++- network/rpc_framework/src/client/pool.rs | 18 +++++++++++++++--- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/base_layer/p2p/src/config.rs b/base_layer/p2p/src/config.rs index 46a07020e9..6cf7c921ba 100644 --- a/base_layer/p2p/src/config.rs +++ b/base_layer/p2p/src/config.rs @@ -103,6 +103,8 @@ pub struct P2pConfig { deserialize_with = "deserialize_from_str", serialize_with = "serialize_string" )] + /// If set to `Private`, the node will not be used as a public relay + /// (Base node default: `Auto`, Wallet default: `Private`) pub reachability_mode: ReachabilityMode, /// The global maximum allowed RPC sessions. /// Default: 100 diff --git a/base_layer/wallet/src/connectivity_service/service.rs b/base_layer/wallet/src/connectivity_service/service.rs index 177e1fe670..c94dab111f 100644 --- a/base_layer/wallet/src/connectivity_service/service.rs +++ b/base_layer/wallet/src/connectivity_service/service.rs @@ -287,6 +287,7 @@ impl WalletConnectivityService { } async fn disconnect_base_node(&mut self, peer_id: PeerId) { + trace!(target: LOG_TARGET, "Disconnecting base node '{}'...", peer_id); if let Some(pool) = self.current_pool.take() { pool.close().await; } @@ -314,9 +315,8 @@ impl WalletConnectivityService { match self.try_setup_rpc_pool(&peer).await { Ok(true) => { - if let Err(e) = self.notify_pending_requests().await { - warn!(target: LOG_TARGET, "Error notifying pending RPC requests: {}", e); - } + self.base_node_watch.send(Some(peer_manager.clone())); + self.notify_pending_requests().await; self.set_online_status(OnlineStatus::Online); debug!( target: LOG_TARGET, @@ -434,16 +434,21 @@ impl WalletConnectivityService { Ok(true) } - async fn notify_pending_requests(&mut self) -> Result<(), WalletConnectivityError> { + async fn notify_pending_requests(&mut self) { let current_pending = mem::take(&mut self.pending_requests); + let mut count = 0; + let current_pending_len = current_pending.len(); for reply in current_pending { if reply.is_canceled() { continue; } - + count += 1; + trace!(target: LOG_TARGET, "Handle {} of {} pending RPC pool requests", count, current_pending_len); self.handle_pool_request(reply).await; } - Ok(()) + if !self.pending_requests.is_empty() { + warn!(target: LOG_TARGET, "{} of {} pending RPC pool requests not handled", count, current_pending_len); + } } } diff --git a/common/config/presets/c_base_node_c.toml b/common/config/presets/c_base_node_c.toml index 05e3cd2010..7988570d04 100644 --- a/common/config/presets/c_base_node_c.toml +++ b/common/config/presets/c_base_node_c.toml @@ -126,6 +126,11 @@ blockchain_sync_config.rpc_deadline = 240 # _NOTE_: If using the `tor` transport type, public_addresses will be ignored and an onion address will be # automatically configured #public_addresses = ["/ip4/172.2.3.4/tcp/18189",] +# The multiaddrs to listen on. +# Default: ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] +#listen_addresses = ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] +# (Base node default: `auto`, Wallet default: `private`) +#reachability_mode = auto # Optionally bind an additional TCP socket for inbound Tari P2P protocol commms. # Use cases include: @@ -163,4 +168,4 @@ blockchain_sync_config.rpc_deadline = 240 # If true, and the maximum per peer RPC sessions is reached, the RPC server will close an old session and replace it # with a new session. If false, the RPC server will reject the new session and preserve the older session. # (default value = true). -#pub cull_oldest_peer_rpc_connection_on_full = true +#cull_oldest_peer_rpc_connection_on_full = true diff --git a/common/config/presets/d_console_wallet.toml b/common/config/presets/d_console_wallet.toml index c0381ff013..3b97fbdea2 100644 --- a/common/config/presets/d_console_wallet.toml +++ b/common/config/presets/d_console_wallet.toml @@ -166,6 +166,12 @@ event_channel_size = 3500 # _NOTE_: If using the `tor` transport type, public_address will be ignored and an onion address will be # automatically configured #public_addresses = ["/ip4/172.2.3.4/tcp/18188",] +# The multiaddrs to listen on. +# Default: ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] +#listen_addresses = ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] +# If set to `Private`, the node will not be used as a public relay +# (Base node default: `auto`, Wallet default: `private`) +#reachability_mode = private # Optionally bind an additional TCP socket for inbound Tari P2P protocol commms. # Use cases include: @@ -205,7 +211,6 @@ event_channel_size = 3500 #rpc_max_simultaneous_sessions = 100 # The maximum comms RPC sessions allowed per peer (default value = 10). #rpc_max_sessions_per_peer = 10 -#rpc_max_sessions_per_peer = 10 # If true, and the maximum per peer RPC sessions is reached, the RPC server will close an old session and replace it # with a new session. If false, the RPC server will reject the new session and preserve the older session. # (default value = true). diff --git a/network/rpc_framework/src/client/pool.rs b/network/rpc_framework/src/client/pool.rs index 3855a4c495..5a66837f6a 100644 --- a/network/rpc_framework/src/client/pool.rs +++ b/network/rpc_framework/src/client/pool.rs @@ -108,10 +108,21 @@ where Ok(c) => c, // This is an edge case where the remote node does not have any further sessions available. This // is gracefully handled by returning one of the existing used sessions. - Err(RpcClientPoolError::NoMoreRemoteRpcSessions) => self - .get_least_used() - .ok_or(RpcClientPoolError::NoMoreRemoteRpcSessions)?, + Err(RpcClientPoolError::NoMoreRemoteRpcSessions) => { + trace!( + target: LOG_TARGET, + "get_least_used_or_connect: no more remote rpc sessions, trying least used." + ); + self.get_least_used().ok_or({ + trace!( + target: LOG_TARGET, + "get_least_used_or_connect: lest used client not found." + ); + RpcClientPoolError::NoMoreRemoteRpcSessions + })? + }, Err(err) => { + trace!(target: LOG_TARGET, "get_least_used_or_connect: returning error ({})", err); return Err(err); }, } @@ -120,6 +131,7 @@ where if !client.is_connected() { self.prune(); + trace!(target: LOG_TARGET, "get_least_used_or_connect: new client is not connected, pruning"); continue; } From f4e430448e7af263f30dc1f0acc7f72e86726da7 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Thu, 7 Nov 2024 05:18:29 +0200 Subject: [PATCH 2/6] fix peer_id not updating --- base_layer/wallet/src/connectivity_service/service.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/base_layer/wallet/src/connectivity_service/service.rs b/base_layer/wallet/src/connectivity_service/service.rs index c94dab111f..6d797d14eb 100644 --- a/base_layer/wallet/src/connectivity_service/service.rs +++ b/base_layer/wallet/src/connectivity_service/service.rs @@ -298,7 +298,6 @@ impl WalletConnectivityService { async fn setup_base_node_connection(&mut self, mut peer_manager: BaseNodePeerManager) { let mut peer = peer_manager.select_next_peer_if_attempted().clone(); - let peer_id = peer.peer_id(); loop { self.set_online_status(OnlineStatus::Connecting); @@ -340,18 +339,18 @@ impl WalletConnectivityService { return; }, }; - self.disconnect_base_node(peer_id).await; + self.disconnect_base_node(peer.peer_id()).await; self.set_online_status(OnlineStatus::Offline); continue; }, Err(WalletConnectivityError::DialError(DialError::Aborted)) => { debug!(target: LOG_TARGET, "Dial was cancelled."); - self.disconnect_base_node(peer_id).await; + self.disconnect_base_node(peer.peer_id()).await; self.set_online_status(OnlineStatus::Offline); }, Err(e) => { warn!(target: LOG_TARGET, "{}", e); - self.disconnect_base_node(peer_id).await; + self.disconnect_base_node(peer.peer_id()).await; self.set_online_status(OnlineStatus::Offline); }, } @@ -359,7 +358,7 @@ impl WalletConnectivityService { // Select the next peer (if available) let next_peer = peer_manager.select_next_peer().clone(); // If we only have one peer in the list, wait a bit before retrying - if peer_id == next_peer.peer_id() { + if peer.peer_id() == next_peer.peer_id() { debug!(target: LOG_TARGET, "Only single peer in base node peer list. Waiting {}s before retrying again ...", CONNECTIVITY_WAIT.as_secs() From 2f404b67d90b5fb7807a21766a7d70ce1c8fd786 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Thu, 7 Nov 2024 12:13:28 +0200 Subject: [PATCH 3/6] further refinements --- .../src/ui/state/wallet_event_monitor.rs | 40 +++++++------------ .../contacts/src/contacts_service/handle.rs | 2 +- .../base_node_peer_manager.rs | 33 +-------------- .../src/connectivity_service/service.rs | 36 +++++------------ 4 files changed, 26 insertions(+), 85 deletions(-) diff --git a/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs b/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs index d24e3b8edd..a999cf0d71 100644 --- a/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs +++ b/applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs @@ -90,11 +90,7 @@ impl WalletEventMonitor { result = transaction_service_events.recv() => { match result { Ok(msg) => { - trace!( - target: LOG_TARGET, - "Wallet Event Monitor received wallet transaction service event {:?}", - msg - ); + trace!(target: LOG_TARGET, "Wallet transaction service event {:?}", msg); self.app_state_inner.write().await.add_event(EventListItem{ event_type: "TransactionEvent".to_string(), desc: (*msg).to_string() @@ -184,27 +180,17 @@ impl WalletEventMonitor { } }, Ok(_) = connectivity_status.changed() => { - trace!(target: LOG_TARGET, "Wallet Event Monitor received wallet connectivity status changed"); + trace!( + target: LOG_TARGET, + "Wallet connectivity status changed to {:?}", + connectivity_status.borrow().clone() + ); self.trigger_peer_state_refresh().await; }, - // Ok(_) = software_update_notif.changed() => { - // trace!(target: LOG_TARGET, "Wallet Event Monitor received wallet auto update status changed"); - // let update = software_update_notif.borrow().as_ref().cloned(); - // if let Some(update) = update { - // self.add_notification(format!( - // "Version {} of the {} is available: {} (sha: {})", - // update.version(), - // update.app(), - // update.download_url(), - // update.to_hash_hex() - // )).await; - // } - // }, - result = network_events.recv() => { - match result { - Ok(msg) => { - trace!(target: LOG_TARGET, "Wallet Event Monitor received wallet connectivity event {:?}", msg - ); + result = network_events.recv() => { + match result { + Ok(msg) => { + trace!(target: LOG_TARGET, "Wallet connectivity event {:?}", msg); match msg { NetworkEvent::PeerConnected{..} | NetworkEvent::PeerDisconnected{..} => { @@ -244,14 +230,16 @@ impl WalletEventMonitor { _ = base_node_changed.changed() => { let peer = base_node_changed.borrow().as_ref().cloned(); if let Some(peer) = peer { - self.trigger_base_node_peer_refresh(peer.get_current_peer().clone()).await; + let current_peer = peer.get_current_peer().clone(); + trace!(target: LOG_TARGET, "Base node changed to '{}'", current_peer.peer_id()); + self.trigger_base_node_peer_refresh(current_peer).await; self.trigger_balance_refresh(); } } result = base_node_events.recv() => { match result { Ok(msg) => { - trace!(target: LOG_TARGET, "Wallet Event Monitor received base node event {:?}", msg); + trace!(target: LOG_TARGET, "Base node event {:?}", msg); if let BaseNodeEvent::BaseNodeStateChanged(state) = (*msg).clone() { self.trigger_base_node_state_refresh(state).await; } diff --git a/base_layer/contacts/src/contacts_service/handle.rs b/base_layer/contacts/src/contacts_service/handle.rs index bd1afeba21..36b72ea3fb 100644 --- a/base_layer/contacts/src/contacts_service/handle.rs +++ b/base_layer/contacts/src/contacts_service/handle.rs @@ -108,7 +108,7 @@ impl Display for ContactsLivenessData { f, "Liveness event '{}' for contact {} ({}) {}", self.message_type, - self.address, + self.address.to_hex(), self.peer_id, if let Some(time) = self.last_seen { let local_time = DateTime::::from_naive_utc_and_offset(time, Local::now().offset().to_owned()) diff --git a/base_layer/wallet/src/connectivity_service/base_node_peer_manager.rs b/base_layer/wallet/src/connectivity_service/base_node_peer_manager.rs index 56c495004a..808a7248e4 100644 --- a/base_layer/wallet/src/connectivity_service/base_node_peer_manager.rs +++ b/base_layer/wallet/src/connectivity_service/base_node_peer_manager.rs @@ -23,7 +23,6 @@ use std::{ fmt::Display, sync::{atomic, atomic::AtomicUsize, Arc}, - time::{Duration, Instant}, }; use tari_network::{identity::PeerId, Peer}; @@ -31,13 +30,12 @@ use tari_network::{identity::PeerId, Peer}; use crate::connectivity_service::WalletConnectivityError; /// The selected peer is a current base node and an optional list of backup peers. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct BaseNodePeerManager { // The current base node that the wallet is connected to current_peer_index: Arc, // The other base nodes that the wallet can connect to if the selected peer is not available peer_list: Arc>, - local_last_connection_attempt: Option, } impl BaseNodePeerManager { @@ -57,7 +55,6 @@ impl BaseNodePeerManager { Ok(Self { current_peer_index: Arc::new(AtomicUsize::new(preferred_peer_index)), peer_list: Arc::new(peer_list), - local_last_connection_attempt: None, }) } @@ -66,13 +63,6 @@ impl BaseNodePeerManager { self.get_current_peer().peer_id() } - pub fn select_next_peer_if_attempted(&mut self) -> &Peer { - if self.time_since_last_connection_attempt().is_some() { - self.select_next_peer(); - } - self.get_current_peer() - } - /// Get the current peer. pub fn get_current_peer(&self) -> &Peer { self.peer_list @@ -84,10 +74,6 @@ impl BaseNodePeerManager { /// Changes to the next peer in the list, returning that peer pub fn select_next_peer(&mut self) -> &Peer { self.set_current_peer_index((self.current_peer_index() + 1) % self.peer_list.len()); - if self.peer_list.len() > 1 { - // Reset the last attempt since we've moved onto another peer - self.local_last_connection_attempt = None; - } &self.peer_list[self.current_peer_index()] } @@ -100,16 +86,6 @@ impl BaseNodePeerManager { (self.current_peer_index(), &self.peer_list) } - /// Set the last connection attempt stats - pub fn set_last_connection_attempt(&mut self) { - self.local_last_connection_attempt = Some(Instant::now()); - } - - /// Get the last connection attempt for the current peer - pub fn time_since_last_connection_attempt(&self) -> Option { - self.local_last_connection_attempt.as_ref().map(|t| t.elapsed()) - } - fn set_current_peer_index(&self, index: usize) { self.current_peer_index.store(index, atomic::Ordering::SeqCst); } @@ -121,15 +97,10 @@ impl BaseNodePeerManager { impl Display for BaseNodePeerManager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let last_connection_attempt = match self.time_since_last_connection_attempt() { - Some(stats) => format!("{:?}", stats.as_secs()), - None => "Never".to_string(), - }; write!( f, - "BaseNodePeerManager {{ current index: {}, last attempt (s): {}, peer list: {} entries }}", + "BaseNodePeerManager {{ current index: {}, peer list: {} entries }}", self.current_peer_index(), - last_connection_attempt, self.peer_list.len() ) } diff --git a/base_layer/wallet/src/connectivity_service/service.rs b/base_layer/wallet/src/connectivity_service/service.rs index 6d797d14eb..eb3f10b3dd 100644 --- a/base_layer/wallet/src/connectivity_service/service.rs +++ b/base_layer/wallet/src/connectivity_service/service.rs @@ -69,6 +69,7 @@ pub struct WalletConnectivityService { current_pool: Option, online_status_watch: Watch, pending_requests: Vec, + last_attempted_peer: Option, } struct ClientPoolContainer { @@ -100,6 +101,7 @@ impl WalletConnectivityService { current_pool: None, pending_requests: Vec::new(), online_status_watch, + last_attempted_peer: None, } } @@ -297,21 +299,14 @@ impl WalletConnectivityService { } async fn setup_base_node_connection(&mut self, mut peer_manager: BaseNodePeerManager) { - let mut peer = peer_manager.select_next_peer_if_attempted().clone(); + let mut peer = if self.last_attempted_peer.is_some() { + peer_manager.select_next_peer().clone() + } else { + peer_manager.get_current_peer().clone() + }; loop { self.set_online_status(OnlineStatus::Connecting); - let maybe_last_attempt = peer_manager.time_since_last_connection_attempt(); - - debug!( - target: LOG_TARGET, - "Attempting to connect to base node peer '{}'... (last attempt {:?})", - peer, - maybe_last_attempt - ); - - peer_manager.set_last_connection_attempt(); - match self.try_setup_rpc_pool(&peer).await { Ok(true) => { self.base_node_watch.send(Some(peer_manager.clone())); @@ -328,20 +323,9 @@ impl WalletConnectivityService { target: LOG_TARGET, "The peer has changed while connecting. Attempting to connect to new base node." ); - - // NOTE: we do not strictly need to update our local copy of BaseNodePeerManager since state is - // atomically shared. However, since None is a possibility (although in practice - // it should never be) we handle that here. - peer_manager = match self.get_base_node_peer_manager() { - Some(pm) => pm, - None => { - warn!(target: LOG_TARGET, "⚠️ NEVER HAPPEN: Base node peer manager set to None while connecting"); - return; - }, - }; self.disconnect_base_node(peer.peer_id()).await; self.set_online_status(OnlineStatus::Offline); - continue; + return; }, Err(WalletConnectivityError::DialError(DialError::Aborted)) => { debug!(target: LOG_TARGET, "Dial was cancelled."); @@ -364,9 +348,6 @@ impl WalletConnectivityService { CONNECTIVITY_WAIT.as_secs() ); time::sleep(CONNECTIVITY_WAIT).await; - } else { - // Ensure that all services are aware of the next peer being attempted - self.base_node_watch.mark_changed(); } peer = next_peer; } @@ -380,6 +361,7 @@ impl WalletConnectivityService { } async fn try_setup_rpc_pool(&mut self, peer: &Peer) -> Result { + self.last_attempted_peer = Some(peer.peer_id()); let peer_id = peer.peer_id(); let dial_wait = self .network_handle From b4655633485aa0e87ae6eee717dfa7bb16c46979 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Thu, 7 Nov 2024 12:25:44 +0200 Subject: [PATCH 4/6] remove mark_changed from Watch --- base_layer/wallet/src/util/watch.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/base_layer/wallet/src/util/watch.rs b/base_layer/wallet/src/util/watch.rs index 7935ec4752..3277713969 100644 --- a/base_layer/wallet/src/util/watch.rs +++ b/base_layer/wallet/src/util/watch.rs @@ -59,18 +59,6 @@ impl Watch { &mut self.1 } - /// Marks the state as changed. - /// - /// After invoking this method [`has_changed()`](Self::has_changed) - /// returns `true` and [`changed()`](Self::changed) returns - /// immediately, regardless of whether a new value has been sent. - /// - /// This is useful for triggering an initial change notification after - /// subscribing to synchronize new receivers. - pub fn mark_changed(&mut self) { - self.receiver_mut().mark_changed(); - } - pub fn get_receiver(&self) -> watch::Receiver { self.receiver().clone() } From a5edcdc0b38f181543f8e5cc7af2590f8700b18d Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Thu, 7 Nov 2024 12:28:32 +0200 Subject: [PATCH 5/6] remove receiver_mut from Watch --- base_layer/wallet/src/util/watch.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/base_layer/wallet/src/util/watch.rs b/base_layer/wallet/src/util/watch.rs index 3277713969..7482b27737 100644 --- a/base_layer/wallet/src/util/watch.rs +++ b/base_layer/wallet/src/util/watch.rs @@ -55,10 +55,6 @@ impl Watch { &self.1 } - fn receiver_mut(&mut self) -> &mut watch::Receiver { - &mut self.1 - } - pub fn get_receiver(&self) -> watch::Receiver { self.receiver().clone() } From 37ed40a67e9cee7ea842b2bf043b9d6d41320ad5 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Thu, 7 Nov 2024 12:34:48 +0200 Subject: [PATCH 6/6] review comments --- base_layer/p2p/src/config.rs | 4 ++-- common/config/presets/c_base_node_c.toml | 3 ++- common/config/presets/d_console_wallet.toml | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/base_layer/p2p/src/config.rs b/base_layer/p2p/src/config.rs index 6cf7c921ba..30e73f099a 100644 --- a/base_layer/p2p/src/config.rs +++ b/base_layer/p2p/src/config.rs @@ -103,8 +103,8 @@ pub struct P2pConfig { deserialize_with = "deserialize_from_str", serialize_with = "serialize_string" )] - /// If set to `Private`, the node will not be used as a public relay - /// (Base node default: `Auto`, Wallet default: `Private`) + /// If set to `Private`, the node assume it has no public address and will try to establish a relay connection as + /// soon as possible. `Auto` will use auto NAT to try determine this automatically. pub reachability_mode: ReachabilityMode, /// The global maximum allowed RPC sessions. /// Default: 100 diff --git a/common/config/presets/c_base_node_c.toml b/common/config/presets/c_base_node_c.toml index 7988570d04..1458fdd251 100644 --- a/common/config/presets/c_base_node_c.toml +++ b/common/config/presets/c_base_node_c.toml @@ -129,7 +129,8 @@ blockchain_sync_config.rpc_deadline = 240 # The multiaddrs to listen on. # Default: ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] #listen_addresses = ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] -# (Base node default: `auto`, Wallet default: `private`) +# If set to `Private`, the node assume it has no public address and will try to establish a relay connection as +# soon as possible. `Auto` will use auto NAT to try determine this automatically. #reachability_mode = auto # Optionally bind an additional TCP socket for inbound Tari P2P protocol commms. diff --git a/common/config/presets/d_console_wallet.toml b/common/config/presets/d_console_wallet.toml index 3b97fbdea2..3e573c299b 100644 --- a/common/config/presets/d_console_wallet.toml +++ b/common/config/presets/d_console_wallet.toml @@ -170,7 +170,8 @@ event_channel_size = 3500 # Default: ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] #listen_addresses = ["/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"] # If set to `Private`, the node will not be used as a public relay -# (Base node default: `auto`, Wallet default: `private`) +# If set to `Private`, the node assume it has no public address and will try to establish a relay connection as +# soon as possible. `Auto` will use auto NAT to try determine this automatically. #reachability_mode = private # Optionally bind an additional TCP socket for inbound Tari P2P protocol commms.