use crate::log::error; use crate::records::memory::response_channels::Command; use crate::rpc::server::handshake::handle_handshake; use crate::sled::Db; use crate::Arc; use crate::Mutex; use crate::SocketAddr; use crate::TcpListener; // wait incomming connections pub async fn start_rpc( db: &Db, server_address: String, wallet_key: String, map: Arc>, ) { // Parse once at startup so the accept loop can work with a concrete // socket address instead of reparsing the settings string each time. let server_socket: SocketAddr = server_address .parse() .expect("Failed to parse server address"); let db_clone = db.clone(); // The listener runs in the background while startup continues with // the rest of node initialization. tokio::spawn(async move { rpc_server(server_socket, &db_clone, wallet_key, map).await; }); } // generate a connection when it comes in async fn rpc_server( server_socket: SocketAddr, db: &Db, wallet_key: String, map: Arc>, ) { // Bind failure means this node cannot accept RPC traffic, so log the // reason and leave the background task instead of panicking. let listener = match TcpListener::bind(&server_socket).await { Ok(listener) => listener, Err(e) => { error!("Failed to bind to socket: {e:?}"); return; } }; loop { match listener.accept().await { Ok((stream, _)) => { // Every accepted socket gets its own handshake task so // slow peers do not block the listener from accepting. let stream = Arc::new(Mutex::new(stream)); let db_clone = db.clone(); let wallet_key_clone = wallet_key.clone(); let map_clone = map.clone(); tokio::spawn(async move { handle_handshake(stream, db_clone, wallet_key_clone, map_clone).await; }); } Err(e) => { error!("Error accepting connection: {e:?}"); } } } }