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
This commit is contained in:
Ivan Sorokin 2018-07-30 02:48:24 +02:00 committed by Ignotus Peverell
parent 61506a8064
commit 5c029e3f87
14 changed files with 114 additions and 99 deletions

View file

@ -38,5 +38,6 @@ env:
- TEST_DIR=keychain
- TEST_DIR=core
- TEST_DIR=util
- TEST_DIR=config
script: cd $TEST_DIR && cargo test --release

17
Cargo.lock generated
View file

@ -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)" = "<none>"
"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"

View file

@ -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"

View file

@ -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);
}

View file

@ -75,14 +75,10 @@ impl From<io::Error> 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<PathBuf>,
/// 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<ConfigMembers>,
}
@ -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)]

20
config/tests/config.rs Normal file
View file

@ -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
);
}

View file

@ -83,7 +83,7 @@ pub enum ChainTypes {
impl Default for ChainTypes {
fn default() -> ChainTypes {
ChainTypes::UserTesting
ChainTypes::Testnet3
}
}

View file

@ -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 = "."

View file

@ -90,7 +90,7 @@ impl<T> From<mpsc::TrySendError<T>> 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

View file

@ -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<usize> {
}
/// 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

View file

@ -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: <u32>::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()),
}
}
}

View file

@ -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,7 +333,16 @@ fn main() {
panic!("Error parsing config file: {}", e);
});
if global_config.using_config_file {
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
@ -357,9 +366,6 @@ fn main() {
.clone()
.chain_type,
);
} else {
init_logger(Some(LoggingConfig::default()));
}
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.");
}
}
}
}
@ -400,17 +399,6 @@ 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
@ -420,9 +408,6 @@ fn server_command(server_args: Option<&ArgMatches>, mut global_config: GlobalCon
.clone()
.chain_type,
);
} else {
panic!("No configuration found.");
}
// just get defaults from the global config
let mut server_config = global_config.members.as_ref().unwrap().server.clone();

View file

@ -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,
}
}

View file

@ -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.