mod datastore; mod grpc; mod http_server; mod persistence; mod sgx; mod solana; use crate::{datastore::LOCALHOST, grpc::challenge::NodeUpdate, solana::Client as SolClient}; use datastore::Store; use solana_sdk::signer::Signer; use std::{ fs::File, io::{BufRead, BufReader}, sync::Arc, }; use tokio::{ sync::{broadcast, broadcast::Sender}, task::JoinSet, time::{sleep, Duration}, }; const INIT_NODES: &str = "detee_challenge_nodes"; const DISK_PERSISTENCE: &str = "TRY_TO_HACK_THIS"; pub async fn localhost_cron(ds: Arc, tx: Sender) { loop { sleep(Duration::from_secs(60)).await; let _ = tx.send((LOCALHOST.to_string(), ds.get_localhost()).into()); ds.remove_inactive_nodes(); } } async fn get_sol_client() -> SolClient { match crate::persistence::Data::read(DISK_PERSISTENCE).await { Ok(data) => { let (keypair, token) = data.parse(); println!("Found the following wallet saved to disk: {}", keypair.pubkey()); println!("Loading token mint address {}", token); return SolClient::from(keypair, token); } Err(e) => println!("Did not find old pubkeys saved to disk: {e}"), }; let input = match File::open(INIT_NODES) { Ok(i) => i, Err(_) => { println!("Could not find remote nodes in the file {INIT_NODES}"); println!("Starting a new network with a new key..."); return SolClient::new().await; } }; let buffered = BufReader::new(input); for line in buffered.lines() { match grpc::client::key_grabber(line.unwrap()).await { Ok(bundle) => { println!( "Got keypair from the network. Joining the network using wallet {}", bundle.0.pubkey() ); println!("The address of the Token is {}", bundle.1.to_string()); println!("Saving this data to disk in the file {DISK_PERSISTENCE}"); let disk_data = crate::persistence::Data::init_from(&bundle.0, &bundle.1).await; if let Err(e) = disk_data.write(DISK_PERSISTENCE).await { println!("Could not save data to disk due to: {e}"); } return SolClient::from(bundle.0, bundle.1); } Err(e) => { println!("Could not get keypair: {e:?}"); } }; } panic!("could not get keypair."); } #[tokio::main] async fn main() { let sol_client = get_sol_client().await; let ds = Arc::new(Store::init(sol_client)); let (tx, mut _rx) = broadcast::channel(500); let mut long_term_tasks = JoinSet::new(); let mut init_tasks = JoinSet::new(); long_term_tasks.spawn(localhost_cron(ds.clone(), tx.clone())); long_term_tasks.spawn(http_server::init(ds.clone())); long_term_tasks.spawn(grpc::server::MyServer::init(ds.clone(), tx.clone()).start()); if let Ok(input) = File::open(INIT_NODES) { let buffered = BufReader::new(input); for line in buffered.lines() { init_tasks.spawn( grpc::client::ConnManager::init(ds.clone(), tx.clone()) .start_with_node(line.unwrap()), ); } } let mut connection_count = 0; while init_tasks.join_next().await.is_some() { if connection_count < 3 { long_term_tasks.spawn(grpc::client::ConnManager::init(ds.clone(), tx.clone()).start()); connection_count += 1; } } while connection_count < 3 { long_term_tasks.spawn(grpc::client::ConnManager::init(ds.clone(), tx.clone()).start()); connection_count += 1; } // exit no matter which task finished long_term_tasks.join_next().await; println!("Shutting down..."); }