diff --git a/crates/core/src/bin/freenet.rs b/crates/core/src/bin/freenet.rs index c1fee8b8e..6e05eb083 100644 --- a/crates/core/src/bin/freenet.rs +++ b/crates/core/src/bin/freenet.rs @@ -4,7 +4,7 @@ use freenet::{ local_node::{Executor, OperationMode}, server::{local_node::run_local_node, network_node::run_network_node}, }; -use std::net::SocketAddr; +use std::{net::SocketAddr, sync::Arc}; type DynError = Box; @@ -18,7 +18,8 @@ async fn run(config: Config) -> Result<(), DynError> { async fn run_local(config: Config) -> Result<(), DynError> { let port = config.ws_api.port; let ip = config.ws_api.address; - let executor = Executor::from_config(&config, None).await?; + let executor = Executor::from_config(Arc::new(config), None).await?; + let socket: SocketAddr = (ip, port).into(); run_local_node(executor, socket).await } diff --git a/crates/core/src/config.rs b/crates/core/src/config.rs index f91686547..71844509a 100644 --- a/crates/core/src/config.rs +++ b/crates/core/src/config.rs @@ -4,7 +4,7 @@ use std::{ io::{Read, Write}, net::{IpAddr, Ipv4Addr}, path::PathBuf, - sync::atomic::AtomicBool, + sync::{atomic::AtomicBool, Arc}, time::Duration, }; @@ -246,7 +246,7 @@ impl ConfigArgs { }, transport_keypair: transport_key.unwrap_or_else(TransportKeypair::new), log_level: self.log_level.unwrap_or(tracing::log::LevelFilter::Info), - config_paths: self.config_paths.build(self.id.as_deref())?, + config_paths: Arc::new(self.config_paths.build(self.id.as_deref())?), }; fs::create_dir_all(&this.config_paths.config_dir)?; @@ -350,7 +350,7 @@ pub struct Config { #[serde(with = "serde_log_level_filter")] pub log_level: tracing::log::LevelFilter, #[serde(flatten)] - config_paths: ConfigPaths, + config_paths: Arc, #[serde(skip)] pub(crate) peer_id: Option, } @@ -359,6 +359,10 @@ impl Config { pub fn transport_keypair(&self) -> &TransportKeypair { &self.transport_keypair } + + pub(crate) fn paths(&self) -> Arc { + self.config_paths.clone() + } } #[derive(clap::Parser, Debug, Default, Copy, Clone, Serialize, Deserialize)] @@ -666,8 +670,56 @@ impl ConfigPaths { self.event_log = event_log; self } + + pub fn iter(&self) -> ConfigPathsIter { + ConfigPathsIter { + curr: 0, + config_paths: self, + } + } + + fn path_by_index(&self, index: usize) -> (bool, &PathBuf) { + match index { + 0 => (true, &self.contracts_dir), + 1 => (true, &self.delegates_dir), + 2 => (true, &self.secrets_dir), + 3 => (true, &self.db_dir), + 4 => (true, &self.data_dir), + 5 => (false, &self.event_log), + 6 => (true, &self.config_dir), + _ => panic!("invalid path index"), + } + } + + const MAX_PATH_INDEX: usize = 6; +} + +pub struct ConfigPathsIter<'a> { + curr: usize, + config_paths: &'a ConfigPaths, } +impl<'a> Iterator for ConfigPathsIter<'a> { + /// The first is whether this path is a directory or a file. + type Item = (bool, &'a PathBuf); + + fn next(&mut self) -> Option { + if self.curr > ConfigPaths::MAX_PATH_INDEX { + None + } else { + let path = self.config_paths.path_by_index(self.curr); + self.curr += 1; + Some(path) + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(ConfigPaths::MAX_PATH_INDEX)) + } +} + +impl<'a> core::iter::FusedIterator for ConfigPathsIter<'a> {} + impl Config { pub fn db_dir(&self) -> PathBuf { self.config_paths.db_dir(self.mode) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 61265986f..c8d4c3c53 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -160,17 +160,17 @@ impl ContractExecutor for Executor { impl Executor { pub async fn from_config( - config: &Config, + config: Arc, event_loop_channel: Option>, ) -> Result { let (contract_store, delegate_store, secret_store, state_store) = - Self::get_stores(config).await?; + Self::get_stores(&config).await?; let rt = Runtime::build(contract_store, delegate_store, secret_store, false).unwrap(); Executor::new( state_store, - || { + move || { // FIXME: potentially not cleaning up after exit - crate::util::set_cleanup_on_exit(None)?; + crate::util::set_cleanup_on_exit(config.paths().clone())?; Ok(()) }, OperationMode::Local, diff --git a/crates/core/src/contract/handler.rs b/crates/core/src/contract/handler.rs index dd500741a..4dbe50ddc 100644 --- a/crates/core/src/contract/handler.rs +++ b/crates/core/src/contract/handler.rs @@ -96,7 +96,7 @@ impl ContractHandler for NetworkContractHandler { where Self: Sized + 'static, { - let executor = Executor::from_config(&config, Some(executor_request_sender)).await?; + let executor = Executor::from_config(config.clone(), Some(executor_request_sender)).await?; Ok(Self { executor, channel }) } diff --git a/crates/core/src/util.rs b/crates/core/src/util.rs index 1b9ddee94..4b2e238e5 100644 --- a/crates/core/src/util.rs +++ b/crates/core/src/util.rs @@ -3,35 +3,45 @@ pub(crate) mod time_source; use std::{ collections::{BTreeMap, HashSet}, net::{Ipv4Addr, SocketAddr, TcpListener}, + sync::Arc, time::Duration, }; +use crate::{config::ConfigPaths, node::PeerId}; use rand::{ prelude::{Rng, StdRng}, SeedableRng, }; -use crate::node::PeerId; - -pub fn set_cleanup_on_exit(id: Option) -> Result<(), ctrlc::Error> { +pub fn set_cleanup_on_exit(config: Arc) -> Result<(), ctrlc::Error> { ctrlc::set_handler(move || { tracing::info!("Received Ctrl+C. Cleaning up..."); #[cfg(debug_assertions)] { - let Ok(path) = crate::config::ConfigPathsArgs::app_data_dir(id.as_deref()) else { - std::process::exit(0); - }; - tracing::info!("Removing content stored at {path:?}"); - - if path.exists() { - let rm = std::fs::remove_dir_all(&path).map_err(|err| { - tracing::warn!("Failed cleaning up directory: {err}"); - err - }); - if rm.is_err() { - tracing::error!("Failed to remove content at {path:?}"); - std::process::exit(-1); + let paths = config.iter(); + for (is_dir, path) in paths { + if path.exists() { + tracing::info!("Removing content stored at {path:?}"); + let rm = if is_dir { + std::fs::remove_dir_all(path).map_err(|err| { + tracing::warn!("Failed cleaning up directory: {err}"); + err + }) + } else { + std::fs::remove_file(path).map_err(|err| { + tracing::warn!("Failed cleaning up file: {err}"); + err + }) + }; + + match rm { + Err(e) if e.kind() != std::io::ErrorKind::NotFound => { + tracing::error!("Failed to remove directory at {path:?}"); + std::process::exit(-1); + } + _ => {} + } } } } diff --git a/crates/fdev/src/wasm_runtime.rs b/crates/fdev/src/wasm_runtime.rs index a0fd8fbce..0bb09a962 100644 --- a/crates/fdev/src/wasm_runtime.rs +++ b/crates/fdev/src/wasm_runtime.rs @@ -1,6 +1,7 @@ use std::{ net::{IpAddr, Ipv4Addr}, path::PathBuf, + sync::Arc, }; use clap::ArgGroup; @@ -18,8 +19,8 @@ pub async fn run_local_executor(config: ExecutorConfig) -> Result<(), anyhow::Er } if config.clean_exit { - // FIXME: potentially not cleaning up the correct directory - freenet::util::set_cleanup_on_exit(None)?; + let paths = config.paths.clone().build(None)?; + freenet::util::set_cleanup_on_exit(Arc::new(paths))?; } let app_state = state::AppState::new(&config).await?;