diff --git a/adapters/celestia/src/lib.rs b/adapters/celestia/src/lib.rs index 2708ca286..7638de48e 100644 --- a/adapters/celestia/src/lib.rs +++ b/adapters/celestia/src/lib.rs @@ -3,9 +3,11 @@ pub mod shares; pub use crate::celestia::*; #[cfg(feature = "native")] -pub mod da_service; +mod da_service; pub mod pfb; pub mod share_commit; pub mod types; mod utils; pub mod verifier; +#[cfg(feature = "native")] +pub use da_service::{CelestiaService, DaServiceConfig}; diff --git a/examples/demo-prover/Cargo.lock b/examples/demo-prover/Cargo.lock index 95f332485..adfbfe2f2 100644 --- a/examples/demo-prover/Cargo.lock +++ b/examples/demo-prover/Cargo.lock @@ -4765,8 +4765,3 @@ dependencies = [ "libc", "pkg-config", ] - -[[patch.unused]] -name = "cc" -version = "1.0.79" -source = "git+https://github.com/rust-lang/cc-rs?rev=e5bbdfa#e5bbdfa1fa468c028cb38fee6c35a3cf2e5a2736" diff --git a/examples/demo-prover/host/benches/prover_bench.rs b/examples/demo-prover/host/benches/prover_bench.rs index d6baf31ed..ed484ece5 100644 --- a/examples/demo-prover/host/benches/prover_bench.rs +++ b/examples/demo-prover/host/benches/prover_bench.rs @@ -7,11 +7,10 @@ use std::str::FromStr; use std::sync::{Arc, Mutex}; use anyhow::Context; -use celestia::da_service::CelestiaService; use celestia::types::{FilteredCelestiaBlock, NamespaceId}; use celestia::verifier::address::CelestiaAddress; -use celestia::verifier::{ChainValidityCondition, RollupParams}; -use celestia::BlobWithSender; +use celestia::verifier::{CelestiaSpec, RollupParams}; +use celestia::CelestiaService; use const_rollup_config::{ROLLUP_NAMESPACE_RAW, SEQUENCER_DA_ADDRESS}; use demo_stf::app::{App, DefaultPrivateKey}; use demo_stf::genesis_config::create_demo_genesis_config; @@ -142,9 +141,10 @@ async fn main() -> Result<(), anyhow::Error> { } let rollup_config_path = "benches/rollup_config.toml".to_string(); - let mut rollup_config: RollupConfig = from_toml_path(&rollup_config_path) - .context("Failed to read rollup configuration") - .unwrap(); + let mut rollup_config: RollupConfig = + from_toml_path(&rollup_config_path) + .context("Failed to read rollup configuration") + .unwrap(); let mut num_blocks = 0; let mut num_blobs = 0; @@ -152,7 +152,7 @@ async fn main() -> Result<(), anyhow::Error> { let mut num_total_transactions = 0; let temp_dir = TempDir::new().expect("Unable to create temporary directory"); - rollup_config.runner.storage.path = PathBuf::from(temp_dir.path()); + rollup_config.storage.path = PathBuf::from(temp_dir.path()); let da_service = CelestiaService::new( rollup_config.da.clone(), @@ -164,8 +164,7 @@ async fn main() -> Result<(), anyhow::Error> { let sequencer_private_key = DefaultPrivateKey::generate(); - let mut app: App = - App::new(rollup_config.runner.storage.clone()); + let mut app: App = App::new(rollup_config.storage.clone()); let sequencer_da_address = CelestiaAddress::from_str(SEQUENCER_DA_ADDRESS).unwrap(); diff --git a/examples/demo-prover/host/benches/rollup_config.toml b/examples/demo-prover/host/benches/rollup_config.toml index d89540e7e..22c57fc90 100644 --- a/examples/demo-prover/host/benches/rollup_config.toml +++ b/examples/demo-prover/host/benches/rollup_config.toml @@ -1,7 +1,3 @@ -# We define the rollup's genesis to occur at Celestia block number `start_height`. The rollup will ignore -# any Celestia blocks before this height -start_height = 1 - [da] # The JWT used to authenticate with the celestia light client. Instructions for generating this token can be found in the README celestia_rpc_auth_token = "MY.SECRET.TOKEN" @@ -10,11 +6,16 @@ celestia_rpc_address = "http://localhost:11111/" # The largest response the rollup will accept from the Celestia node. Defaults to 100 MB max_celestia_response_body_size = 104_857_600 -[runner.storage] +[storage] # The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. path = "benches/demo_data" -[rpc_config] +[runner] +# We define the rollup's genesis to occur at block number `start_height`. The rollup will ignore +# any blocks before this height +start_height = 1 + +[runner.rpc_config] # the host and port to bind the rpc server for bind_host = "127.0.0.1" bind_port = 12345 diff --git a/examples/demo-prover/host/rollup_config.toml b/examples/demo-prover/host/rollup_config.toml index efe60a309..3560c1212 100644 --- a/examples/demo-prover/host/rollup_config.toml +++ b/examples/demo-prover/host/rollup_config.toml @@ -1,8 +1,20 @@ -start_height = 671431 [da] celestia_rpc_auth_token = "SUPER_SECRET_TOKEN" celestia_rpc_address = "http://localhost:11111/" # 100 MB max_celestia_response_body_size = 104_857_600 + +[storage] +# The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. +path = "demo_data" + [runner.storage] path = "demo_data" + +[runner] +start_height = 671431 + +[runner.rpc_config] +# the host and port to bind the rpc server for +bind_host = "127.0.0.1" +bind_port = 12345 diff --git a/examples/demo-prover/host/src/main.rs b/examples/demo-prover/host/src/main.rs index 742845f77..b5cb04314 100644 --- a/examples/demo-prover/host/src/main.rs +++ b/examples/demo-prover/host/src/main.rs @@ -2,31 +2,23 @@ use std::env; use std::str::FromStr; use anyhow::Context; -use celestia::da_service::{CelestiaService, DaServiceConfig}; use celestia::types::NamespaceId; use celestia::verifier::address::CelestiaAddress; use celestia::verifier::{CelestiaSpec, RollupParams}; +use celestia::{CelestiaService, DaServiceConfig}; use const_rollup_config::{ROLLUP_NAMESPACE_RAW, SEQUENCER_DA_ADDRESS}; use demo_stf::app::{App, DefaultPrivateKey}; use demo_stf::genesis_config::create_demo_genesis_config; use methods::{ROLLUP_ELF, ROLLUP_ID}; use risc0_adapter::host::{Risc0Host, Risc0Verifier}; -use serde::Deserialize; use sov_modules_api::PrivateKey; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; use sov_rollup_interface::zk::ZkvmHost; use sov_state::Storage; -use sov_stf_runner::{from_toml_path, Config as RunnerConfig}; +use sov_stf_runner::{from_toml_path, RollupConfig}; use tracing::{info, Level}; -#[derive(Debug, Clone, PartialEq, Deserialize)] -pub struct RollupConfig { - pub start_height: u64, - pub da: DaServiceConfig, - pub runner: RunnerConfig, -} - // The rollup stores its data in the namespace b"sov-test" on Celestia const ROLLUP_NAMESPACE: NamespaceId = NamespaceId(ROLLUP_NAMESPACE_RAW); @@ -44,7 +36,7 @@ async fn main() -> Result<(), anyhow::Error> { let rollup_config_path = env::args() .nth(1) .unwrap_or_else(|| "rollup_config.toml".to_string()); - let rollup_config: RollupConfig = + let rollup_config: RollupConfig = from_toml_path(&rollup_config_path).context("Failed to read rollup configuration")?; let da_service = CelestiaService::new( @@ -57,7 +49,7 @@ async fn main() -> Result<(), anyhow::Error> { let sequencer_private_key = DefaultPrivateKey::generate(); - let mut app: App = App::new(rollup_config.runner.storage.clone()); + let mut app: App = App::new(rollup_config.storage.clone()); let is_storage_empty = app.get_storage().is_empty(); @@ -79,7 +71,7 @@ async fn main() -> Result<(), anyhow::Error> { .get_state_root(&Default::default()) .expect("The storage needs to have a state root"); - for height in rollup_config.start_height.. { + for height in rollup_config.runner.start_height.. { let mut host = Risc0Host::new(ROLLUP_ELF); host.write_to_guest(prev_state_root); info!( diff --git a/examples/demo-prover/methods/guest/Cargo.lock b/examples/demo-prover/methods/guest/Cargo.lock index 3b2641dc1..7b2c0d114 100644 --- a/examples/demo-prover/methods/guest/Cargo.lock +++ b/examples/demo-prover/methods/guest/Cargo.lock @@ -274,6 +274,34 @@ dependencies = [ "jobserver", ] +[[package]] +name = "celestia" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.2", + "bech32", + "borsh", + "hex", + "hex-literal", + "nmt-rs", + "prost", + "prost-build", + "prost-types", + "risc0-zkvm", + "risc0-zkvm-platform", + "serde", + "serde_json", + "sha2 0.10.6", + "sov-rollup-interface", + "tendermint", + "tendermint-proto", + "thiserror", + "tracing", + "zk-cycle-macros", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1058,34 +1086,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jupiter" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "base64 0.21.2", - "bech32", - "borsh", - "hex", - "hex-literal", - "nmt-rs", - "prost", - "prost-build", - "prost-types", - "risc0-zkvm", - "risc0-zkvm-platform", - "serde", - "serde_json", - "sha2 0.10.6", - "sov-rollup-interface", - "tendermint", - "tendermint-proto", - "thiserror", - "tracing", - "zk-cycle-macros", -] - [[package]] name = "keccak" version = "0.1.4" @@ -2053,11 +2053,11 @@ version = "0.1.0" dependencies = [ "anyhow", "borsh", + "celestia", "const-rollup-config", "demo-stf", "directories", "downloader", - "jupiter", "log", "risc0-adapter", "risc0-zkvm", diff --git a/examples/demo-rollup/benches/rollup_bench.rs b/examples/demo-rollup/benches/rollup_bench.rs index 9656f3910..7e6514b75 100644 --- a/examples/demo-rollup/benches/rollup_bench.rs +++ b/examples/demo-rollup/benches/rollup_bench.rs @@ -33,18 +33,19 @@ fn rollup_bench(_bench: &mut Criterion) { .sample_size(10) .measurement_time(Duration::from_secs(20)); let rollup_config_path = "benches/rollup_config.toml".to_string(); - let mut rollup_config: RollupConfig = from_toml_path(&rollup_config_path) - .context("Failed to read rollup configuration") - .unwrap(); + let mut rollup_config: RollupConfig = + from_toml_path(&rollup_config_path) + .context("Failed to read rollup configuration") + .unwrap(); let temp_dir = TempDir::new().expect("Unable to create temporary directory"); - rollup_config.runner.storage.path = PathBuf::from(temp_dir.path()); + rollup_config.storage.path = PathBuf::from(temp_dir.path()); let ledger_db = - LedgerDB::with_path(&rollup_config.runner.storage.path).expect("Ledger DB failed to open"); + LedgerDB::with_path(&rollup_config.storage.path).expect("Ledger DB failed to open"); let da_service = Arc::new(RngDaService::new()); - let demo_runner = App::::new(rollup_config.runner.storage); + let demo_runner = App::::new(rollup_config.storage); let mut demo = demo_runner.stf; let sequencer_private_key = DefaultPrivateKey::generate(); diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index 80acb5233..0333e7fa5 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -81,18 +81,19 @@ async fn main() -> Result<(), anyhow::Error> { } let rollup_config_path = "benches/rollup_config.toml".to_string(); - let mut rollup_config: RollupConfig = from_toml_path(&rollup_config_path) - .context("Failed to read rollup configuration") - .unwrap(); + let mut rollup_config: RollupConfig = + from_toml_path(&rollup_config_path) + .context("Failed to read rollup configuration") + .unwrap(); let temp_dir = TempDir::new().expect("Unable to create temporary directory"); - rollup_config.runner.storage.path = PathBuf::from(temp_dir.path()); + rollup_config.storage.path = PathBuf::from(temp_dir.path()); let ledger_db = - LedgerDB::with_path(&rollup_config.runner.storage.path).expect("Ledger DB failed to open"); + LedgerDB::with_path(&rollup_config.storage.path).expect("Ledger DB failed to open"); let da_service = Arc::new(RngDaService::new()); - let demo_runner = App::::new(rollup_config.runner.storage); + let demo_runner = App::::new(rollup_config.storage); let mut demo = demo_runner.stf; let sequencer_private_key = DefaultPrivateKey::generate(); diff --git a/examples/demo-rollup/benches/rollup_config.toml b/examples/demo-rollup/benches/rollup_config.toml index d2fa8b654..1f8e74250 100644 --- a/examples/demo-rollup/benches/rollup_config.toml +++ b/examples/demo-rollup/benches/rollup_config.toml @@ -1,7 +1,3 @@ -# We define the rollup's genesis to occur at Celestia block number `start_height`. The rollup will ignore -# any Celestia blocks before this height -start_height = 1 - [da] # The JWT used to authenticate with the celestia light client. Instructions for generating this token can be found in the README celestia_rpc_auth_token = "MY.SECRET.TOKEN" @@ -12,11 +8,16 @@ max_celestia_response_body_size = 104_857_600 # The maximum time to wait for a response to an RPC query against Celestia node. Defaults to 60 seconds. celestia_rpc_timeout_seconds = 60 -[runner.storage] +[storage] # The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. path = "benches/demo_data" -[rpc_config] +[runner] +# We define the rollup's genesis to occur at block number `start_height`. The rollup will ignore +# any blocks before this height +start_height = 1 + +[runner.rpc_config] # the host and port to bind the rpc server for bind_host = "127.0.0.1" bind_port = 12345 diff --git a/examples/demo-rollup/rollup_config.toml b/examples/demo-rollup/rollup_config.toml index 73fd49c4d..1aaf8160f 100644 --- a/examples/demo-rollup/rollup_config.toml +++ b/examples/demo-rollup/rollup_config.toml @@ -1,7 +1,3 @@ -# We define the rollup's genesis to occur at Celestia block number `start_height`. The rollup will ignore -# any Celestia blocks before this height -start_height = 1 - [da] # The JWT used to authenticate with the celestia light client. Instructions for generating this token can be found in the README celestia_rpc_auth_token = "MY.SECRET.TOKEN" @@ -12,11 +8,16 @@ max_celestia_response_body_size = 104_857_600 # The maximum time to wait for a response to an RPC query against Celestia node. Defaults to 60 seconds. celestia_rpc_timeout_seconds = 60 -[runner.storage] +[storage] # The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. path = "demo_data" -[rpc_config] +# We define the rollup's genesis to occur at block number `start_height`. The rollup will ignore +# any blocks before this height +[runner] +start_height = 1 + +[runner.rpc_config] # the host and port to bind the rpc server for bind_host = "127.0.0.1" bind_port = 12345 diff --git a/examples/demo-rollup/src/main.rs b/examples/demo-rollup/src/main.rs index be6de9832..6e7abc70a 100644 --- a/examples/demo-rollup/src/main.rs +++ b/examples/demo-rollup/src/main.rs @@ -1,8 +1,8 @@ use std::env; use anyhow::Context; -use celestia::da_service::CelestiaService; use celestia::verifier::RollupParams; +use celestia::CelestiaService; use demo_stf::app::{App, DefaultContext}; use demo_stf::runtime::get_rpc_methods; #[cfg(feature = "experimental")] @@ -13,7 +13,6 @@ use sov_rollup_interface::services::da::DaService; use sov_state::storage::Storage; use sov_stf_runner::{from_toml_path, RollupConfig, StateTransitionRunner}; use tracing::{debug, Level}; - #[cfg(test)] mod test_rpc; @@ -28,7 +27,7 @@ async fn main() -> Result<(), anyhow::Error> { .unwrap_or_else(|| "rollup_config.toml".to_string()); debug!("Starting demo rollup with config {}", rollup_config_path); - let rollup_config: RollupConfig = + let rollup_config: RollupConfig = from_toml_path(&rollup_config_path).context("Failed to read rollup configuration")?; // Initializing logging @@ -39,7 +38,7 @@ async fn main() -> Result<(), anyhow::Error> { .map_err(|_err| eprintln!("Unable to set global default subscriber")) .expect("Cannot fail to set subscriber"); - let ledger_db = initialize_ledger(&rollup_config.runner.storage.path); + let ledger_db = initialize_ledger(&rollup_config.storage.path); let da_service = CelestiaService::new( rollup_config.da.clone(), @@ -49,7 +48,7 @@ async fn main() -> Result<(), anyhow::Error> { ) .await; - let mut app = App::new(rollup_config.runner.storage.clone()); + let mut app = App::new(rollup_config.storage.clone()); let storage = app.get_storage(); let mut methods = get_rpc_methods::(storage); @@ -66,7 +65,7 @@ async fn main() -> Result<(), anyhow::Error> { let genesis_config = get_genesis_config(); let mut runner = StateTransitionRunner::new( - rollup_config, + rollup_config.runner, da_service, ledger_db, app.stf, diff --git a/examples/demo-stf/src/sov-cli/native.rs b/examples/demo-stf/src/sov-cli/native.rs index ccbfbfd32..0a08c9e5e 100644 --- a/examples/demo-stf/src/sov-cli/native.rs +++ b/examples/demo-stf/src/sov-cli/native.rs @@ -353,7 +353,6 @@ mod test { use sov_rollup_interface::mocks::{MockAddress, MockBlob, MockDaSpec, MockZkvm}; use sov_rollup_interface::stf::StateTransitionFunction; use sov_state::WorkingSet; - use sov_stf_runner::Config; use super::*; @@ -437,13 +436,11 @@ mod test { &election_admin_private_key, ); - let runner_config = Config { - storage: sov_state::config::Config { path }, - }; + let runner_config = sov_state::config::Config { path }; Self { config: genesis_config, - demo: App::::new(runner_config.storage).stf, + demo: App::::new(runner_config).stf, } } } diff --git a/full-node/sov-stf-runner/src/config.rs b/full-node/sov-stf-runner/src/config.rs index 0384df764..a206ec1f4 100644 --- a/full-node/sov-stf-runner/src/config.rs +++ b/full-node/sov-stf-runner/src/config.rs @@ -1,7 +1,18 @@ -use celestia::da_service::DaServiceConfig; +use std::fs::File; +use std::io::Read; +use std::path::Path; + +use serde::de::DeserializeOwned; use serde::Deserialize; +pub use sov_state::config::Config as StorageConfig; -use crate::runner_config::Config as RunnerConfig; +#[derive(Debug, Clone, PartialEq, Deserialize)] +pub struct RunnerConfig { + /// DA start height. + pub start_height: u64, + /// RPC configuration. + pub rpc_config: RpcConfig, +} /// RPC configuration. #[derive(Debug, Clone, PartialEq, Deserialize)] @@ -14,15 +25,26 @@ pub struct RpcConfig { /// Rollup Configuration #[derive(Debug, Clone, PartialEq, Deserialize)] -pub struct RollupConfig { - /// DA start height. - pub start_height: u64, - /// DA configuration. - pub da: DaServiceConfig, +pub struct RollupConfig { /// Runner configuration. + pub storage: StorageConfig, + /// TODO pub runner: RunnerConfig, - /// RPC configuration. - pub rpc_config: RpcConfig, + /// DA configuration. + pub da: DaServiceConfig, +} + +/// Reads toml file as a specific type. +pub fn from_toml_path, R: DeserializeOwned>(path: P) -> anyhow::Result { + let mut contents = String::new(); + { + let mut file = File::open(path)?; + file.read_to_string(&mut contents)?; + } + + let result: R = toml::from_str(&contents)?; + + Ok(result) } #[cfg(test)] @@ -33,7 +55,6 @@ mod tests { use tempfile::NamedTempFile; use super::*; - use crate::runner_config::{from_toml_path, StorageConfig}; fn create_config_from(content: &str) -> NamedTempFile { let mut config_file = NamedTempFile::new().unwrap(); @@ -44,37 +65,40 @@ mod tests { #[test] fn test_correct_config() { let config = r#" - start_height = 31337 [da] celestia_rpc_auth_token = "SECRET_RPC_TOKEN" celestia_rpc_address = "http://localhost:11111/" max_celestia_response_body_size = 980 - [runner.storage] + [storage] path = "/tmp" - [rpc_config] + [runner] + start_height = 31337 + [runner.rpc_config] bind_host = "127.0.0.1" bind_port = 12345 "#; let config_file = create_config_from(config); - let config: RollupConfig = from_toml_path(config_file.path()).unwrap(); + let config: RollupConfig = + from_toml_path(config_file.path()).unwrap(); let expected = RollupConfig { - start_height: 31337, - da: DaServiceConfig { + runner: RunnerConfig { + start_height: 31337, + rpc_config: RpcConfig { + bind_host: "127.0.0.1".to_string(), + bind_port: 12345, + }, + }, + + da: celestia::DaServiceConfig { celestia_rpc_auth_token: "SECRET_RPC_TOKEN".to_string(), celestia_rpc_address: "http://localhost:11111/".into(), max_celestia_response_body_size: 980, celestia_rpc_timeout_seconds: 60, }, - runner: RunnerConfig { - storage: StorageConfig { - path: PathBuf::from("/tmp"), - }, - }, - rpc_config: RpcConfig { - bind_host: "127.0.0.1".to_string(), - bind_port: 12345, + storage: StorageConfig { + path: PathBuf::from("/tmp"), }, }; assert_eq!(config, expected); diff --git a/full-node/sov-stf-runner/src/lib.rs b/full-node/sov-stf-runner/src/lib.rs index ebef9d3b1..69c003315 100644 --- a/full-node/sov-stf-runner/src/lib.rs +++ b/full-node/sov-stf-runner/src/lib.rs @@ -3,15 +3,15 @@ mod batch_builder; mod config; -pub use config::RpcConfig; -mod runner_config; use std::net::SocketAddr; + +pub use config::RpcConfig; mod ledger_rpc; pub use batch_builder::FiFoStrictBatchBuilder; -pub use config::RollupConfig; +use config::RunnerConfig; +pub use config::{from_toml_path, RollupConfig, StorageConfig}; use jsonrpsee::RpcModule; pub use ledger_rpc::get_ledger_rpc; -pub use runner_config::{from_toml_path, Config, StorageConfig}; use sov_db::ledger_db::{LedgerDB, SlotCommit}; use sov_rollup_interface::da::DaSpec; use sov_rollup_interface::services::da::DaService; @@ -60,14 +60,14 @@ where { /// Creates a new `StateTransitionRunner` runner. pub fn new( - rollup_config: RollupConfig, + runner_config: RunnerConfig, da_service: DA, ledger_db: LedgerDB, mut app: ST, should_init_chain: bool, genesis_config: InitialState, ) -> Result { - let rpc_config = rollup_config.rpc_config; + let rpc_config = runner_config.rpc_config; let prev_state_root = { // Check if the rollup has previously been initialized @@ -87,7 +87,7 @@ where // Start the main rollup loop let item_numbers = ledger_db.get_next_items_numbers(); let last_slot_processed_before_shutdown = item_numbers.slot_number - 1; - let start_height = rollup_config.start_height + last_slot_processed_before_shutdown; + let start_height = runner_config.start_height + last_slot_processed_before_shutdown; Ok(Self { start_height, diff --git a/full-node/sov-stf-runner/src/runner_config.rs b/full-node/sov-stf-runner/src/runner_config.rs deleted file mode 100644 index fb7d4ebdc..000000000 --- a/full-node/sov-stf-runner/src/runner_config.rs +++ /dev/null @@ -1,93 +0,0 @@ -use std::fs::File; -use std::io::Read; -use std::path::Path; - -use serde::de::DeserializeOwned; -pub use sov_state::config::Config as StorageConfig; - -/// Reads toml file as a specific type. -pub fn from_toml_path, R: DeserializeOwned>(path: P) -> anyhow::Result { - let mut contents = String::new(); - { - let mut file = File::open(path)?; - file.read_to_string(&mut contents)?; - } - - let result: R = toml::from_str(&contents)?; - - Ok(result) -} - -/// StateTransitionRunner configuration -#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct Config { - /// Storage config - pub storage: StorageConfig, -} - -#[cfg(test)] -mod tests { - use std::io::Write; - use std::path::PathBuf; - - use tempfile::{tempdir, NamedTempFile}; - - use super::*; - - fn create_config_from(content: &str) -> NamedTempFile { - let mut config_file = NamedTempFile::new().unwrap(); - config_file.write_all(content.as_bytes()).unwrap(); - config_file - } - - #[test] - fn test_correct_config() { - let config = r#" - [storage] - path = "/tmp" - "#; - - let config_file = create_config_from(config); - - let config: Config = from_toml_path(config_file.path()).unwrap(); - let expected = Config { - storage: StorageConfig { - path: PathBuf::from("/tmp"), - }, - }; - assert_eq!(config, expected); - } - - #[test] - fn test_incorrect_path() { - // Not closed quote - let config = r#" - [storage] - path = "/tmp - "#; - let config_file = create_config_from(config); - - let config: anyhow::Result = from_toml_path(config_file.path()); - - assert!(config.is_err()); - let error = config.unwrap_err().to_string(); - let expected_error = format!( - "{}{}{}", - "TOML parse error at line 3, column 25\n |\n3 |", - " path = \"/tmp\n | ^\n", - "invalid basic string\n" - ); - assert_eq!(error, expected_error); - } - // - #[test] - fn test_non_existent_config() { - let dir = tempdir().unwrap(); - let path = dir.path().join("non_existing_config.toml"); - - let config: anyhow::Result = from_toml_path(path); - - assert!(config.is_err()); - assert!(config.unwrap_err().to_string().ends_with("(os error 2)")); - } -}