use crate::common::network_startup::get_connections; use crate::log::{error, info}; use crate::miner::flag::{ clear_mining_stop_request, set_mining_state, set_node_mode, MiningState, NodeMode, }; use crate::records::memory::response_channels::Command; use crate::rpc::client::handshake::connect_and_handshake; use crate::rpc::client::structs::Connect; use crate::sled::Db; use crate::sleep; use crate::wallets::structures::Wallet; use crate::Arc; use crate::Duration; use crate::Mutex; pub async fn handle_connections( db: Db, wallet: Arc, map: Arc>, ) -> Result<(), String> { // A zero outgoing limit means this node should not open any bootstrap // connection during startup. let outgoing_connections = crate::Settings::load() .map(|settings| settings.outgoing_connections) .unwrap_or(0); if outgoing_connections == 0 { info!("OUTGOING_CONNECTIONS is 0; skipping startup bootstrap."); set_node_mode(NodeMode::Normal); clear_mining_stop_request(); set_mining_state(MiningState::Idle); return Ok(()); } // try the configured bootstrap peers one by one until a // handshake succeeds or the list is exhausted let filtered_servers = get_connections().await; let mut last_error: Option = None; for server in filtered_servers { // build the outbound handshake request using cloned // shared state so each attempt can run independently let db_clone = db.clone(); // parse the configured peer string once before spawning // the outbound connection attempt let socket_address = server.parse().expect("Failed to parse the socket address"); // Clone the Arc for use in other async functions let map_clone = Arc::clone(&map); let first: bool = true; let connect_params = Connect { addr: socket_address, db: db_clone, node_ip: server.to_string(), wallet: wallet.clone(), map: map_clone, first, }; let err_string = match connect_and_handshake(connect_params).await { Ok(()) => { info!("Connected to {server}"); return Ok(()); } Err(err) => err.to_string(), }; // A peer can reject us because it already has this connection recorded. // In that case retrying other bootstrap peers would not fix the local duplicate state. if err_string.contains("The connection is already in the connection manager Please wait 10 minutes and try again") { return Err(err_string); } error!("Error connecting to {server}: {err_string}"); last_error = Some(err_string.clone()); sleep(Duration::from_secs(5)).await; } if let Some(err) = last_error { info!("No bootstrap peers connected during startup: {err}"); } else { info!("No bootstrap peers connected during startup."); } // Startup can continue as a standalone node even if no bootstrap peer is reachable. set_node_mode(NodeMode::Normal); clear_mining_stop_request(); set_mining_state(MiningState::Idle); Ok(()) }