From 5c029e3f879aa6078657478ee30dc7a6dfb42743 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Mon, 30 Jul 2018 02:48:24 +0200 Subject: [PATCH] Make grin.toml config optional (#1278) * Make grin.toml config optional. Mirror exisiting config parameters in grin.toml to source code, so binary can run without a config file. Add test for it. * fixup! Make grin.toml config optional --- .travis.yml | 1 + Cargo.lock | 17 +++++++ config/Cargo.toml | 3 ++ config/src/config.rs | 4 +- config/src/types.rs | 8 +--- config/tests/config.rs | 20 ++++++++ core/src/global.rs | 6 +-- grin.toml | 2 +- p2p/src/types.rs | 15 ++---- pool/src/types.rs | 4 +- servers/src/common/types.rs | 24 +++++----- src/bin/grin.rs | 95 ++++++++++++++++--------------------- util/src/types.rs | 12 ++--- wallet/src/types.rs | 2 +- 14 files changed, 114 insertions(+), 99 deletions(-) create mode 100644 config/tests/config.rs diff --git a/.travis.yml b/.travis.yml index 86c5b8d42..bcc522766 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,5 +38,6 @@ env: - TEST_DIR=keychain - TEST_DIR=core - TEST_DIR=util + - TEST_DIR=config script: cd $TEST_DIR && cargo test --release diff --git a/Cargo.lock b/Cargo.lock index 7d91aa1c7..282e50f44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -381,6 +381,11 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "dtoa" version = "0.2.2" @@ -619,6 +624,7 @@ dependencies = [ "grin_servers 0.3.0", "grin_util 0.3.0", "grin_wallet 0.3.0", + "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1426,6 +1432,15 @@ name = "podio" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pretty_assertions" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "prettytable-rs" version = "0.7.0" @@ -2303,6 +2318,7 @@ dependencies = [ "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" "checksum cursive 0.8.2-alpha.0 (git+https://github.com/yeastplume/Cursive?tag=grin_integration_1)" = "" "checksum daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4093d27eb267d617f03c2ee25d4c3ca525b89a76154001954a11984508ffbde5" +"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" @@ -2394,6 +2410,7 @@ dependencies = [ "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" +"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5511ca4c805aa35f0abff6be7923231d664408b60c09f44ef715f2bce106cd9e" "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6" diff --git a/config/Cargo.toml b/config/Cargo.toml index e91dc6dc3..f0ae385f8 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -14,3 +14,6 @@ grin_servers = { path = "../servers" } grin_p2p = { path = "../p2p" } grin_util = { path = "../util" } grin_wallet = { path = "../wallet"} + +[dev-dependencies] +pretty_assertions = "0.5.1" diff --git a/config/src/config.rs b/config/src/config.rs index d49855659..ee5bea5ea 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -48,7 +48,6 @@ impl Default for GlobalConfig { fn default() -> GlobalConfig { GlobalConfig { config_file_path: None, - using_config_file: false, members: Some(ConfigMembers::default()), } } @@ -112,7 +111,7 @@ impl GlobalConfig { ))); } - // Try to parse the config file if it exists explode if it does exist but + // Try to parse the config file if it exists, explode if it does exist but // something's wrong with it return_value.read_config() } @@ -128,7 +127,6 @@ impl GlobalConfig { // Put the struct back together, because the config // file was flattened a bit gc.server.stratum_mining_config = gc.mining_server.clone(); - self.using_config_file = true; self.members = Some(gc); return Ok(self); } diff --git a/config/src/types.rs b/config/src/types.rs index bde5afb06..ad88826df 100644 --- a/config/src/types.rs +++ b/config/src/types.rs @@ -75,14 +75,10 @@ impl From for ConfigError { /// as they tend to be quite nested in the code /// Most structs optional, as they may or may not /// be needed depending on what's being run -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct GlobalConfig { /// Keep track of the file we've read pub config_file_path: Option, - /// keep track of whether we're using - /// a config file or just the defaults - /// for each member - pub using_config_file: bool, /// Global member config pub members: Option, } @@ -91,7 +87,7 @@ pub struct GlobalConfig { /// level GlobalConfigContainer options might want to keep /// internal state that we don't necessarily /// want serialised or deserialised -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct ConfigMembers { /// Server config #[serde(default)] diff --git a/config/tests/config.rs b/config/tests/config.rs new file mode 100644 index 000000000..24ba76515 --- /dev/null +++ b/config/tests/config.rs @@ -0,0 +1,20 @@ +#[macro_use] +extern crate pretty_assertions; +extern crate grin_config as config; + +use config::GlobalConfig; + +#[test] +fn file_config_equal_to_defaults() { + let x = true; + let global_config_without_file = GlobalConfig::default(); + + let global_config_with_file = GlobalConfig::new(Some("../grin.toml")).unwrap_or_else(|e| { + panic!("Error parsing config file: {}", e); + }); + + assert_eq!( + global_config_without_file.members, + global_config_with_file.members + ); +} diff --git a/core/src/global.rs b/core/src/global.rs index e1ad69361..f01e4eaa2 100644 --- a/core/src/global.rs +++ b/core/src/global.rs @@ -83,7 +83,7 @@ pub enum ChainTypes { impl Default for ChainTypes { fn default() -> ChainTypes { - ChainTypes::UserTesting + ChainTypes::Testnet3 } } @@ -245,11 +245,11 @@ where } let mut interval_index = live_intervals.len() - 1; let mut last_ts = last_n.first().as_ref().unwrap().as_ref().unwrap().0; - let last_diff = live_intervals[live_intervals.len()-1].1; + let last_diff = live_intervals[live_intervals.len() - 1].1; // fill in simulated blocks with values from the previous real block for _ in 0..block_count_difference { - last_ts = last_ts.saturating_sub(live_intervals[live_intervals.len()-1].0); + last_ts = last_ts.saturating_sub(live_intervals[live_intervals.len() - 1].0); last_n.insert(0, Ok((last_ts, last_diff.clone()))); interval_index = match interval_index { 0 => live_intervals.len() - 1, diff --git a/grin.toml b/grin.toml index 25c7dedcd..41dbcda04 100644 --- a/grin.toml +++ b/grin.toml @@ -149,7 +149,7 @@ api_listen_interface = "127.0.0.1" api_listen_port = 13415 # Where the wallet should find a running node -check_node_api_http_addr = "http://localhost:13413" +check_node_api_http_addr = "http://127.0.0.1:13413" # Where to find wallet files (seed, data, etc) data_file_dir = "." diff --git a/p2p/src/types.rs b/p2p/src/types.rs index e66aeaa0e..be2407f54 100644 --- a/p2p/src/types.rs +++ b/p2p/src/types.rs @@ -90,7 +90,7 @@ impl From> for Error { } /// Configuration for the peer-to-peer server. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct P2PConfig { pub host: IpAddr, pub port: u16, @@ -115,9 +115,9 @@ impl Default for P2PConfig { port: 13414, peers_allow: None, peers_deny: None, - ban_window: Some(BAN_WINDOW), - peer_max_count: Some(PEER_MAX_COUNT), - peer_min_preferred_count: Some(PEER_MIN_PREFERRED_COUNT), + ban_window: None, + peer_max_count: None, + peer_min_preferred_count: None, } } } @@ -266,12 +266,7 @@ pub trait ChainAdapter: Sync + Send { /// If we're willing to accept that new state, the data stream will be /// read as a zip file, unzipped and the resulting state files should be /// rewound to the provided indexes. - fn txhashset_write( - &self, - h: Hash, - txhashset_data: File, - peer_addr: SocketAddr, - ) -> bool; + fn txhashset_write(&self, h: Hash, txhashset_data: File, peer_addr: SocketAddr) -> bool; } /// Additional methods required by the protocol that don't need to be diff --git a/pool/src/types.rs b/pool/src/types.rs index 709c5c9ac..b33333cd6 100644 --- a/pool/src/types.rs +++ b/pool/src/types.rs @@ -35,7 +35,7 @@ const DANDELION_STEM_PROBABILITY: usize = 90; /// Configuration for "Dandelion". /// Note: shared between p2p and pool. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct DandelionConfig { /// Choose new Dandelion relay peer every n secs. #[serde = "default_dandelion_relay_secs"] @@ -81,7 +81,7 @@ fn default_dandelion_stem_probability() -> Option { } /// Transaction pool configuration -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct PoolConfig { /// Base fee for a transaction to be accepted by the pool. The transaction /// weight is computed from its number of inputs, outputs and kernels and diff --git a/servers/src/common/types.rs b/servers/src/common/types.rs index 24235f5ee..a14d3c51b 100644 --- a/servers/src/common/types.rs +++ b/servers/src/common/types.rs @@ -126,7 +126,7 @@ impl Default for Seeding { /// Full server configuration, aggregating configurations required for the /// different components. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ServerConfig { /// Directory under which the rocksdb stores will be created pub db_root: String, @@ -200,7 +200,7 @@ impl Default for ServerConfig { fn default() -> ServerConfig { ServerConfig { db_root: ".grin".to_string(), - api_http_addr: "0.0.0.0:13413".to_string(), + api_http_addr: "127.0.0.1:13413".to_string(), capabilities: p2p::Capabilities::FULL_NODE, seeding_type: Seeding::default(), seeds: None, @@ -211,11 +211,11 @@ impl Default for ServerConfig { archive_mode: None, chain_validation_mode: ChainValidationMode::default(), pool_config: pool::PoolConfig::default(), - skip_sync_wait: None, - run_tui: None, - run_wallet_listener: Some(false), - run_wallet_owner_api: Some(false), - use_db_wallet: Some(false), + skip_sync_wait: Some(false), + run_tui: Some(true), + run_wallet_listener: Some(true), + run_wallet_owner_api: Some(true), + use_db_wallet: None, run_test_miner: Some(false), test_miner_wallet_url: None, } @@ -223,7 +223,7 @@ impl Default for ServerConfig { } /// Stratum (Mining server) configuration -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct StratumServerConfig { /// Run a stratum mining server (the only way to communicate to mine this /// node via grin-miner @@ -250,12 +250,12 @@ pub struct StratumServerConfig { impl Default for StratumServerConfig { fn default() -> StratumServerConfig { StratumServerConfig { - wallet_listener_url: "http://localhost:13415".to_string(), + wallet_listener_url: "http://127.0.0.1:13415".to_string(), burn_reward: false, - attempt_time_per_block: ::max_value(), + attempt_time_per_block: 15, minimum_share_difficulty: 1, - enable_stratum_server: None, - stratum_server_addr: None, + enable_stratum_server: Some(true), + stratum_server_addr: Some("127.0.0.1:13416".to_string()), } } } diff --git a/src/bin/grin.rs b/src/bin/grin.rs index 2c3d1a7a8..511cd680b 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -52,7 +52,7 @@ use config::GlobalConfig; use core::core::amount_to_hr_string; use core::global; use tui::ui; -use util::{init_logger, LoggingConfig, LOGGER}; +use util::{init_logger, LOGGER}; use wallet::{libwallet, HTTPWalletClient, LMDBBackend, WalletConfig, WalletInst}; // include build information @@ -333,33 +333,39 @@ fn main() { panic!("Error parsing config file: {}", e); }); - if global_config.using_config_file { - // initialize the logger - let mut log_conf = global_config + if let Some(file_path) = &global_config.config_file_path { + info!( + LOGGER, + "Found configuration file at {}", + file_path.to_str().unwrap() + ); + } else { + info!(LOGGER, "configuration file not found, using default"); + } + + // initialize the logger + let mut log_conf = global_config + .members + .as_mut() + .unwrap() + .logging + .clone() + .unwrap(); + let run_tui = global_config.members.as_mut().unwrap().server.run_tui; + if run_tui.is_some() && run_tui.unwrap() && args.subcommand().0 != "wallet" { + log_conf.log_to_stdout = false; + log_conf.tui_running = Some(true); + } + init_logger(Some(log_conf)); + global::set_mining_mode( + global_config .members .as_mut() .unwrap() - .logging + .server .clone() - .unwrap(); - let run_tui = global_config.members.as_mut().unwrap().server.run_tui; - if run_tui.is_some() && run_tui.unwrap() && args.subcommand().0 != "wallet" { - log_conf.log_to_stdout = false; - log_conf.tui_running = Some(true); - } - init_logger(Some(log_conf)); - global::set_mining_mode( - global_config - .members - .as_mut() - .unwrap() - .server - .clone() - .chain_type, - ); - } else { - init_logger(Some(LoggingConfig::default())); - } + .chain_type, + ); log_build_info(); @@ -383,14 +389,7 @@ fn main() { // this could possibly become the way to configure most things // with most command line options being phased out _ => { - if global_config.using_config_file { - server_command(None, global_config); - } else { - // won't attempt to just start with defaults, - // and will reject - println!("Unknown command, and no configuration file was found."); - println!("Use 'grin help' for a list of all commands."); - } + server_command(None, global_config); } } } @@ -400,29 +399,15 @@ fn main() { /// arguments /// to build a proper configuration and runs Grin with that configuration. fn server_command(server_args: Option<&ArgMatches>, mut global_config: GlobalConfig) { - if global_config.using_config_file { - info!( - LOGGER, - "Starting the Grin server from configuration file at {}", - global_config - .config_file_path - .as_ref() - .unwrap() - .to_str() - .unwrap() - ); - global::set_mining_mode( - global_config - .members - .as_mut() - .unwrap() - .server - .clone() - .chain_type, - ); - } else { - panic!("No configuration found."); - } + global::set_mining_mode( + global_config + .members + .as_mut() + .unwrap() + .server + .clone() + .chain_type, + ); // just get defaults from the global config let mut server_config = global_config.members.as_ref().unwrap().server.clone(); diff --git a/util/src/types.rs b/util/src/types.rs index 31517a971..5ebdf72fd 100644 --- a/util/src/types.rs +++ b/util/src/types.rs @@ -15,7 +15,7 @@ //! Logging configuration types /// Log level types, as slog's don't implement serialize -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum LogLevel { /// Critical Critical, @@ -32,7 +32,7 @@ pub enum LogLevel { } /// Logging config -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct LoggingConfig { /// whether to log to stdout pub log_to_stdout: bool, @@ -54,11 +54,11 @@ impl Default for LoggingConfig { fn default() -> LoggingConfig { LoggingConfig { log_to_stdout: true, - stdout_log_level: LogLevel::Debug, - log_to_file: false, - file_log_level: LogLevel::Trace, + stdout_log_level: LogLevel::Warning, + log_to_file: true, + file_log_level: LogLevel::Debug, log_file_path: String::from("grin.log"), - log_file_append: false, + log_file_append: true, tui_running: None, } } diff --git a/wallet/src/types.rs b/wallet/src/types.rs index bd3f45746..38cbade35 100644 --- a/wallet/src/types.rs +++ b/wallet/src/types.rs @@ -29,7 +29,7 @@ use util::LOGGER; pub const SEED_FILE: &'static str = "wallet.seed"; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct WalletConfig { // Right now the decision to run or not a wallet is based on the command. // This may change in the near-future.