mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Config + Default directories (#1433)
* config file can now be generated by executable * rustfmt * remove now-unnecessary config defaults test * set up paths and config file creation in user's home directory * rustfmt * remove default grin.toml * add grin configuration command to spit out config file * Split configuration into wallet and server * rustfmt * Restore logging to wallet configurations * rustfmt
This commit is contained in:
parent
471e80e69e
commit
1ded3f3972
19 changed files with 955 additions and 381 deletions
469
config/src/comments.rs
Normal file
469
config/src/comments.rs
Normal file
|
@ -0,0 +1,469 @@
|
||||||
|
// Copyright 2018 The Grin Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! Comments for configuration + injection into output .toml
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// maps entries to Comments that should preceed them
|
||||||
|
fn comments() -> HashMap<String, String> {
|
||||||
|
let mut retval = HashMap::new();
|
||||||
|
retval.insert(
|
||||||
|
"[server]".to_string(),
|
||||||
|
"
|
||||||
|
# Sample Server Configuration File for Grin
|
||||||
|
#
|
||||||
|
# When running the grin executable without specifying any command line
|
||||||
|
# arguments, it will look for this file in three places, in the following
|
||||||
|
# order:
|
||||||
|
#
|
||||||
|
# -The working directory
|
||||||
|
# -The directory in which the executable resides
|
||||||
|
# -[user home]/.grin
|
||||||
|
#
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
### SERVER CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
#Server connection details
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"api_http_addr".to_string(),
|
||||||
|
"
|
||||||
|
#the address on which services will listen, e.g. Transaction Pool
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"db_root".to_string(),
|
||||||
|
"
|
||||||
|
#the directory, relative to current, in which the grin blockchain
|
||||||
|
#is stored
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"chain_type".to_string(),
|
||||||
|
"
|
||||||
|
#The chain type, which defines the genesis block and the set of cuckoo
|
||||||
|
#parameters used for mining. Can be:
|
||||||
|
#AutomatedTesting - For CI builds and instant blockchain creation
|
||||||
|
#UserTesting - For regular user testing (cuckoo 16)
|
||||||
|
#Testnet1 - Testnet1 genesis block (cuckoo 16)
|
||||||
|
#Testnet2 - Testnet2 genesis block (cuckoo 30)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"chain_validation_mode".to_string(),
|
||||||
|
"
|
||||||
|
#The chain validation mode, defines how often (if at all) we
|
||||||
|
#want to run a full chain validation. Can be:
|
||||||
|
#\"EveryBlock\" - run full chain validation when processing each block (except during sync)
|
||||||
|
#\"Disabled\" - disable full chain validation (just run regular block validation)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"archive_mode".to_string(),
|
||||||
|
"
|
||||||
|
#run the node in \"full archive\" mode (default is fast-sync, pruned node)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"skip_sync_wait".to_string(),
|
||||||
|
"
|
||||||
|
#skip waiting for sync on startup, (optional param, mostly for testing)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"run_tui".to_string(),
|
||||||
|
"
|
||||||
|
#whether to run the ncurses TUI. Ncurses must be installed and this
|
||||||
|
#will also disable logging to stdout
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"run_wallet_listener".to_string(),
|
||||||
|
"
|
||||||
|
#Whether to run the wallet listener with the server by default
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"run_wallet_owner_api".to_string(),
|
||||||
|
"
|
||||||
|
# Whether to run the web-wallet API (will only run on localhost)
|
||||||
|
# grin wallet web will run this automatically, so this should
|
||||||
|
# only be set to true for test/development purposes
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"run_test_miner".to_string(),
|
||||||
|
"
|
||||||
|
#Whether to run a test miner. This is only for developer testing (chaintype
|
||||||
|
#usertesting) at cuckoo 16, and will only mine into the default wallet port.
|
||||||
|
#real mining should use the standalone grin-miner
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[server.dandelion_config]".to_string(),
|
||||||
|
"
|
||||||
|
#########################################
|
||||||
|
### DANDELION CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"relay_secs".to_string(),
|
||||||
|
"
|
||||||
|
#dandelion relay time (choose new relay peer every n secs)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"embargo_secs".to_string(),
|
||||||
|
"
|
||||||
|
#fluff and broadcast after embargo expires if tx not seen on network
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"patience_secs".to_string(),
|
||||||
|
"
|
||||||
|
#run dandelion stem/fluff processing every n secs (stem tx aggregation in this window)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
retval.insert(
|
||||||
|
"stem_probability".to_string(),
|
||||||
|
"
|
||||||
|
#dandelion stem probability (stem 90% of the time, fluff 10% of the time)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[server.p2p_config]".to_string(),
|
||||||
|
"#test miner wallet URL (burns if this doesn't exist)
|
||||||
|
#test_miner_wallet_url = \"http://127.0.0.1:13415\"
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
### SERVER P2P CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
#The P2P server details (i.e. the server that communicates with other
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"host".to_string(),
|
||||||
|
"
|
||||||
|
#The interface on which to listen.
|
||||||
|
#0.0.0.0 will listen on all interfaces, alowing others to interact
|
||||||
|
#127.0.0.1 will listen on the local machine only
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"port".to_string(),
|
||||||
|
"
|
||||||
|
#The port on which to listen.
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"seeding_type".to_string(),
|
||||||
|
"
|
||||||
|
#How to seed this server, can be None, List, WebStatic or DNSSeed
|
||||||
|
#If the seeding type is List, the list of peers to connect to can
|
||||||
|
#be specified as follows:
|
||||||
|
#seeds = [\"192.168.0.1:13414\",\"192.168.0.2:13414\"]
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"seeds".to_string(),
|
||||||
|
"
|
||||||
|
#If seeding_type = List, the list of peers to connect to.
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[server.p2p_config.capabilities]".to_string(),
|
||||||
|
"#7 = Bit flags for FULL_NODE, this structure needs to be changed
|
||||||
|
#internally to make it more configurable
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[server.pool_config]".to_string(),
|
||||||
|
"#hardcoded peer lists for allow/deny
|
||||||
|
#will *only* connect to peers in allow list
|
||||||
|
#peers_allow = [\"192.168.0.1:13414\", \"192.168.0.2:13414\"]
|
||||||
|
#will *never* connect to peers in deny list
|
||||||
|
#peers_deny = [\"192.168.0.3:13414\", \"192.168.0.4:13414\"]
|
||||||
|
#a list of preferred peers to connect to
|
||||||
|
#peers_preferred = [\"192.168.0.1:13414\",\"192.168.0.2:13414\"]
|
||||||
|
|
||||||
|
#how long a banned peer should stay banned
|
||||||
|
#ban_window = 10800
|
||||||
|
|
||||||
|
#maximum number of peers
|
||||||
|
#peer_max_count = 25
|
||||||
|
|
||||||
|
#preferred minimum number of peers (we'll actively keep trying to add peers
|
||||||
|
#until we get to at least this number
|
||||||
|
#peer_min_preferred_count = 8
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
### MEMPOOL CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"accept_fee_base".to_string(),
|
||||||
|
"
|
||||||
|
#Base fee that's accepted into the pool
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"max_pool_size".to_string(),
|
||||||
|
"
|
||||||
|
#Maximum number of transactions allowed in the pool
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[server.stratum_mining_config]".to_string(),
|
||||||
|
"
|
||||||
|
################################################
|
||||||
|
### STRATUM MINING SERVER CONFIGURATION ###
|
||||||
|
################################################
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"enable_stratum_server".to_string(),
|
||||||
|
"
|
||||||
|
#whether stratum server is enabled
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"stratum_server_addr".to_string(),
|
||||||
|
"
|
||||||
|
#what port and address for the stratum server to listen on
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"attempt_time_per_block".to_string(),
|
||||||
|
"
|
||||||
|
#The amount of time, in seconds, to attempt to mine on a particular
|
||||||
|
#header before stopping and re-collecting transactions from the pool
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"minimum_share_difficulty".to_string(),
|
||||||
|
"
|
||||||
|
#The minimum acceptable share difficulty to request from miners
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"wallet_listener_url".to_string(),
|
||||||
|
"
|
||||||
|
#the wallet receiver to which coinbase rewards will be sent
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"burn_reward".to_string(),
|
||||||
|
"
|
||||||
|
#whether to ignore the reward (mostly for testing)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[wallet]".to_string(),
|
||||||
|
"
|
||||||
|
#########################################
|
||||||
|
### WALLET CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"api_listen_interface".to_string(),
|
||||||
|
"
|
||||||
|
# Host IP for wallet listener, change to \"0.0.0.0\" to receive grins
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"api_listen_port".to_string(),
|
||||||
|
"
|
||||||
|
# Port for wallet listener
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"check_node_api_http_addr".to_string(),
|
||||||
|
"
|
||||||
|
# Where the wallet should find a running node
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"data_file_dir".to_string(),
|
||||||
|
"
|
||||||
|
# Where to find wallet files (seed, data, etc)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"[logging]".to_string(),
|
||||||
|
"
|
||||||
|
#########################################
|
||||||
|
### LOGGING CONFIGURATION ###
|
||||||
|
#########################################
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"log_to_stdout".to_string(),
|
||||||
|
"
|
||||||
|
# Whether to log to stdout
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"stdout_log_level".to_string(),
|
||||||
|
"
|
||||||
|
# Log level for stdout: Critical, Error, Warning, Info, Debug, Trace
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"log_to_file".to_string(),
|
||||||
|
"
|
||||||
|
# Whether to log to a file
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"file_log_level".to_string(),
|
||||||
|
"
|
||||||
|
# Log level for file: Critical, Error, Warning, Info, Debug, Trace
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"log_file_path".to_string(),
|
||||||
|
"
|
||||||
|
# Log file path
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval.insert(
|
||||||
|
"log_file_append".to_string(),
|
||||||
|
"
|
||||||
|
# Whether to append to the log file (true), or replace it on every run (false)
|
||||||
|
"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_key(line: &str) -> String {
|
||||||
|
if line.contains("[") && line.contains("]") {
|
||||||
|
return line.to_owned();
|
||||||
|
} else if line.contains("=") {
|
||||||
|
return line.split("=").collect::<Vec<&str>>()[0].trim().to_owned();
|
||||||
|
} else {
|
||||||
|
return "NOT_FOUND".to_owned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_comments(orig: String) -> String {
|
||||||
|
let comments = comments();
|
||||||
|
let lines: Vec<&str> = orig.split("\n").collect();
|
||||||
|
let mut out_lines = vec![];
|
||||||
|
for l in lines {
|
||||||
|
let key = get_key(l);
|
||||||
|
if let Some(v) = comments.get(&key) {
|
||||||
|
out_lines.push(v.to_owned());
|
||||||
|
}
|
||||||
|
out_lines.push(l.to_owned());
|
||||||
|
out_lines.push("\n".to_owned());
|
||||||
|
}
|
||||||
|
let mut ret_val = String::from("");
|
||||||
|
for l in out_lines {
|
||||||
|
ret_val.push_str(&l);
|
||||||
|
}
|
||||||
|
ret_val.to_owned()
|
||||||
|
}
|
|
@ -14,33 +14,123 @@
|
||||||
|
|
||||||
//! Configuration file management
|
//! Configuration file management
|
||||||
|
|
||||||
use dirs;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::{self, File};
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
use servers::{ServerConfig, StratumServerConfig};
|
use comments::insert_comments;
|
||||||
use types::{ConfigError, ConfigMembers, GlobalConfig};
|
use servers::ServerConfig;
|
||||||
|
use types::{
|
||||||
|
ConfigError, ConfigMembers, GlobalConfig, GlobalWalletConfig, GlobalWalletConfigMembers,
|
||||||
|
};
|
||||||
use util::LoggingConfig;
|
use util::LoggingConfig;
|
||||||
use wallet::WalletConfig;
|
use wallet::WalletConfig;
|
||||||
|
|
||||||
/// The default file name to use when trying to derive
|
/// The default file name to use when trying to derive
|
||||||
/// the config file location
|
/// the node config file location
|
||||||
|
pub const SERVER_CONFIG_FILE_NAME: &'static str = "grin-server.toml";
|
||||||
const CONFIG_FILE_NAME: &'static str = "grin.toml";
|
/// And a wallet configuration file name
|
||||||
|
pub const WALLET_CONFIG_FILE_NAME: &'static str = "grin-wallet.toml";
|
||||||
|
const SERVER_LOG_FILE_NAME: &'static str = "grin-server.log";
|
||||||
|
const WALLET_LOG_FILE_NAME: &'static str = "grin-wallet.log";
|
||||||
const GRIN_HOME: &'static str = ".grin";
|
const GRIN_HOME: &'static str = ".grin";
|
||||||
|
const GRIN_CHAIN_DIR: &'static str = "chain_data";
|
||||||
|
const GRIN_WALLET_DIR: &'static str = "wallet_data";
|
||||||
|
|
||||||
|
fn get_grin_path() -> Result<PathBuf, ConfigError> {
|
||||||
|
// Check if grin dir exists
|
||||||
|
let grin_path = {
|
||||||
|
match env::home_dir() {
|
||||||
|
Some(mut p) => {
|
||||||
|
p.push(GRIN_HOME);
|
||||||
|
p
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut pb = PathBuf::new();
|
||||||
|
pb.push(GRIN_HOME);
|
||||||
|
pb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Create if the default path doesn't exist
|
||||||
|
if !grin_path.exists() {
|
||||||
|
fs::create_dir_all(grin_path.clone())?;
|
||||||
|
}
|
||||||
|
Ok(grin_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_config_current_dir(path: &str) -> Option<PathBuf> {
|
||||||
|
let p = env::current_dir();
|
||||||
|
let mut c = match p {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(_) => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
c.push(path);
|
||||||
|
if c.exists() {
|
||||||
|
return Some(c);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles setup and detection of paths for node
|
||||||
|
pub fn initial_setup_server() -> Result<GlobalConfig, ConfigError> {
|
||||||
|
// Use config file if current directory if it exists, .grin home otherwise
|
||||||
|
if let Some(p) = check_config_current_dir(SERVER_CONFIG_FILE_NAME) {
|
||||||
|
GlobalConfig::new(p.to_str().unwrap())
|
||||||
|
} else {
|
||||||
|
// Check if grin dir exists
|
||||||
|
let grin_path = get_grin_path()?;
|
||||||
|
|
||||||
|
// Get path to default config file
|
||||||
|
let mut config_path = grin_path.clone();
|
||||||
|
config_path.push(SERVER_CONFIG_FILE_NAME);
|
||||||
|
|
||||||
|
// Spit it out if it doesn't exist
|
||||||
|
if !config_path.exists() {
|
||||||
|
let mut default_config = GlobalConfig::default();
|
||||||
|
// update paths relative to current dir
|
||||||
|
default_config.update_paths(&grin_path);
|
||||||
|
default_config.write_to_file(config_path.to_str().unwrap())?;
|
||||||
|
}
|
||||||
|
GlobalConfig::new(config_path.to_str().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles setup and detection of paths for wallet
|
||||||
|
pub fn initial_setup_wallet() -> Result<GlobalWalletConfig, ConfigError> {
|
||||||
|
// Use config file if current directory if it exists, .grin home otherwise
|
||||||
|
if let Some(p) = check_config_current_dir(WALLET_CONFIG_FILE_NAME) {
|
||||||
|
GlobalWalletConfig::new(p.to_str().unwrap())
|
||||||
|
} else {
|
||||||
|
// Check if grin dir exists
|
||||||
|
let grin_path = get_grin_path()?;
|
||||||
|
|
||||||
|
// Get path to default config file
|
||||||
|
let mut config_path = grin_path.clone();
|
||||||
|
config_path.push(WALLET_CONFIG_FILE_NAME);
|
||||||
|
|
||||||
|
// Spit it out if it doesn't exist
|
||||||
|
if !config_path.exists() {
|
||||||
|
let mut default_config = GlobalWalletConfig::default();
|
||||||
|
// update paths relative to current dir
|
||||||
|
default_config.update_paths(&grin_path);
|
||||||
|
default_config.write_to_file(config_path.to_str().unwrap())?;
|
||||||
|
}
|
||||||
|
GlobalWalletConfig::new(config_path.to_str().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the defaults, as strewn throughout the code
|
/// Returns the defaults, as strewn throughout the code
|
||||||
|
|
||||||
impl Default for ConfigMembers {
|
impl Default for ConfigMembers {
|
||||||
fn default() -> ConfigMembers {
|
fn default() -> ConfigMembers {
|
||||||
ConfigMembers {
|
ConfigMembers {
|
||||||
server: ServerConfig::default(),
|
server: ServerConfig::default(),
|
||||||
mining_server: Some(StratumServerConfig::default()),
|
|
||||||
logging: Some(LoggingConfig::default()),
|
logging: Some(LoggingConfig::default()),
|
||||||
wallet: WalletConfig::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,55 +144,29 @@ impl Default for GlobalConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for GlobalWalletConfigMembers {
|
||||||
|
fn default() -> GlobalWalletConfigMembers {
|
||||||
|
GlobalWalletConfigMembers {
|
||||||
|
logging: Some(LoggingConfig::default()),
|
||||||
|
wallet: WalletConfig::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GlobalWalletConfig {
|
||||||
|
fn default() -> GlobalWalletConfig {
|
||||||
|
GlobalWalletConfig {
|
||||||
|
config_file_path: None,
|
||||||
|
members: Some(GlobalWalletConfigMembers::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GlobalConfig {
|
impl GlobalConfig {
|
||||||
/// Need to decide on rules where to read the config file from,
|
/// Requires the path to a config file
|
||||||
/// but will take a stab at logic for now
|
pub fn new(file_path: &str) -> Result<GlobalConfig, ConfigError> {
|
||||||
|
|
||||||
fn derive_config_location(&mut self) -> Result<(), ConfigError> {
|
|
||||||
// First, check working directory
|
|
||||||
let mut config_path = env::current_dir().unwrap();
|
|
||||||
config_path.push(CONFIG_FILE_NAME);
|
|
||||||
if config_path.exists() {
|
|
||||||
self.config_file_path = Some(config_path);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
// Next, look in directory of executable
|
|
||||||
let mut config_path = env::current_exe().unwrap();
|
|
||||||
config_path.pop();
|
|
||||||
config_path.push(CONFIG_FILE_NAME);
|
|
||||||
if config_path.exists() {
|
|
||||||
self.config_file_path = Some(config_path);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
// Then look in {user_home}/.grin
|
|
||||||
let config_path = dirs::home_dir();
|
|
||||||
if let Some(mut p) = config_path {
|
|
||||||
p.push(GRIN_HOME);
|
|
||||||
p.push(CONFIG_FILE_NAME);
|
|
||||||
if p.exists() {
|
|
||||||
self.config_file_path = Some(p);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Give up
|
|
||||||
Err(ConfigError::FileNotFoundError(String::from("")))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes the path to a config file, or if NONE, tries to determine a config
|
|
||||||
/// file based on rules in derive_config_location
|
|
||||||
pub fn new(file_path: Option<&str>) -> Result<GlobalConfig, ConfigError> {
|
|
||||||
let mut return_value = GlobalConfig::default();
|
let mut return_value = GlobalConfig::default();
|
||||||
if let Some(fp) = file_path {
|
return_value.config_file_path = Some(PathBuf::from(&file_path));
|
||||||
return_value.config_file_path = Some(PathBuf::from(&fp));
|
|
||||||
} else {
|
|
||||||
let _result = return_value.derive_config_location();
|
|
||||||
}
|
|
||||||
|
|
||||||
// No attempt at a config file, just return defaults
|
|
||||||
if let None = return_value.config_file_path {
|
|
||||||
return Ok(return_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config file path is given but not valid
|
// Config file path is given but not valid
|
||||||
let config_file = return_value.config_file_path.clone().unwrap();
|
let config_file = return_value.config_file_path.clone().unwrap();
|
||||||
|
@ -124,10 +188,7 @@ impl GlobalConfig {
|
||||||
file.read_to_string(&mut contents)?;
|
file.read_to_string(&mut contents)?;
|
||||||
let decoded: Result<ConfigMembers, toml::de::Error> = toml::from_str(&contents);
|
let decoded: Result<ConfigMembers, toml::de::Error> = toml::from_str(&contents);
|
||||||
match decoded {
|
match decoded {
|
||||||
Ok(mut gc) => {
|
Ok(gc) => {
|
||||||
// Put the struct back together, because the config
|
|
||||||
// file was flattened a bit
|
|
||||||
gc.server.stratum_mining_config = gc.mining_server.clone();
|
|
||||||
self.members = Some(gc);
|
self.members = Some(gc);
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +208,37 @@ impl GlobalConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update paths
|
||||||
|
pub fn update_paths(&mut self, grin_home: &PathBuf) {
|
||||||
|
// need to update server chain path
|
||||||
|
let mut chain_path = grin_home.clone();
|
||||||
|
chain_path.push(GRIN_CHAIN_DIR);
|
||||||
|
self.members.as_mut().unwrap().server.db_root = chain_path.to_str().unwrap().to_owned();
|
||||||
|
let mut log_path = grin_home.clone();
|
||||||
|
log_path.push(SERVER_LOG_FILE_NAME);
|
||||||
|
self.members
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.logging
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.log_file_path = log_path.to_str().unwrap().to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable mining
|
||||||
|
pub fn stratum_enabled(&mut self) -> bool {
|
||||||
|
return self
|
||||||
|
.members
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.server
|
||||||
|
.stratum_mining_config
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.enable_stratum_server
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize config
|
/// Serialize config
|
||||||
pub fn ser_config(&mut self) -> Result<String, ConfigError> {
|
pub fn ser_config(&mut self) -> Result<String, ConfigError> {
|
||||||
let encoded: Result<String, toml::ser::Error> =
|
let encoded: Result<String, toml::ser::Error> =
|
||||||
|
@ -162,20 +254,101 @@ impl GlobalConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*pub fn wallet_enabled(&mut self) -> bool {
|
/// Write configuration to a file
|
||||||
return self.members.as_mut().unwrap().wallet.as_mut().unwrap().enable_wallet;
|
pub fn write_to_file(&mut self, name: &str) -> Result<(), ConfigError> {
|
||||||
}*/
|
let conf_out = self.ser_config()?;
|
||||||
|
let conf_out = insert_comments(conf_out);
|
||||||
/// Enable mining
|
let mut file = File::create(name)?;
|
||||||
pub fn stratum_enabled(&mut self) -> bool {
|
file.write_all(conf_out.as_bytes())?;
|
||||||
return self
|
Ok(())
|
||||||
.members
|
}
|
||||||
.as_mut()
|
}
|
||||||
.unwrap()
|
|
||||||
.mining_server
|
/// TODO: Properly templatize these structs (if it's worth the effort)
|
||||||
.as_mut()
|
impl GlobalWalletConfig {
|
||||||
.unwrap()
|
/// Requires the path to a config file
|
||||||
.enable_stratum_server
|
pub fn new(file_path: &str) -> Result<GlobalWalletConfig, ConfigError> {
|
||||||
.unwrap();
|
let mut return_value = GlobalWalletConfig::default();
|
||||||
|
return_value.config_file_path = Some(PathBuf::from(&file_path));
|
||||||
|
|
||||||
|
// Config file path is given but not valid
|
||||||
|
let config_file = return_value.config_file_path.clone().unwrap();
|
||||||
|
if !config_file.exists() {
|
||||||
|
return Err(ConfigError::FileNotFoundError(String::from(
|
||||||
|
config_file.to_str().unwrap(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to parse the config file if it exists, explode if it does exist but
|
||||||
|
// something's wrong with it
|
||||||
|
return_value.read_config()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read config
|
||||||
|
fn read_config(mut self) -> Result<GlobalWalletConfig, ConfigError> {
|
||||||
|
let mut file = File::open(self.config_file_path.as_mut().unwrap())?;
|
||||||
|
let mut contents = String::new();
|
||||||
|
file.read_to_string(&mut contents)?;
|
||||||
|
let decoded: Result<GlobalWalletConfigMembers, toml::de::Error> = toml::from_str(&contents);
|
||||||
|
match decoded {
|
||||||
|
Ok(gc) => {
|
||||||
|
self.members = Some(gc);
|
||||||
|
return Ok(self);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(ConfigError::ParseError(
|
||||||
|
String::from(
|
||||||
|
self.config_file_path
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
),
|
||||||
|
String::from(format!("{}", e)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update paths
|
||||||
|
pub fn update_paths(&mut self, wallet_home: &PathBuf) {
|
||||||
|
let mut wallet_path = wallet_home.clone();
|
||||||
|
wallet_path.push(GRIN_WALLET_DIR);
|
||||||
|
self.members.as_mut().unwrap().wallet.data_file_dir =
|
||||||
|
wallet_path.to_str().unwrap().to_owned();
|
||||||
|
let mut log_path = wallet_home.clone();
|
||||||
|
log_path.push(WALLET_LOG_FILE_NAME);
|
||||||
|
self.members
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.logging
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.log_file_path = log_path.to_str().unwrap().to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serialize config
|
||||||
|
pub fn ser_config(&mut self) -> Result<String, ConfigError> {
|
||||||
|
let encoded: Result<String, toml::ser::Error> =
|
||||||
|
toml::to_string(self.members.as_mut().unwrap());
|
||||||
|
match encoded {
|
||||||
|
Ok(enc) => return Ok(enc),
|
||||||
|
Err(e) => {
|
||||||
|
return Err(ConfigError::SerializationError(String::from(format!(
|
||||||
|
"{}",
|
||||||
|
e
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write configuration to a file
|
||||||
|
pub fn write_to_file(&mut self, name: &str) -> Result<(), ConfigError> {
|
||||||
|
let conf_out = self.ser_config()?;
|
||||||
|
let conf_out = insert_comments(conf_out);
|
||||||
|
let mut file = File::create(name)?;
|
||||||
|
file.write_all(conf_out.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#![deny(unused_mut)]
|
#![deny(unused_mut)]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate dirs;
|
extern crate dirs;
|
||||||
|
@ -31,7 +30,9 @@ extern crate grin_servers as servers;
|
||||||
extern crate grin_util as util;
|
extern crate grin_util as util;
|
||||||
extern crate grin_wallet as wallet;
|
extern crate grin_wallet as wallet;
|
||||||
|
|
||||||
|
mod comments;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use types::{ConfigError, ConfigMembers, GlobalConfig};
|
pub use config::{initial_setup_server, initial_setup_wallet};
|
||||||
|
pub use types::{ConfigError, ConfigMembers, GlobalConfig, GlobalWalletConfig};
|
||||||
|
|
|
@ -18,7 +18,7 @@ use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use servers::{ServerConfig, StratumServerConfig};
|
use servers::ServerConfig;
|
||||||
use util::LoggingConfig;
|
use util::LoggingConfig;
|
||||||
use wallet::WalletConfig;
|
use wallet::WalletConfig;
|
||||||
|
|
||||||
|
@ -92,14 +92,25 @@ pub struct ConfigMembers {
|
||||||
/// Server config
|
/// Server config
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub server: ServerConfig,
|
pub server: ServerConfig,
|
||||||
/// Mining config
|
|
||||||
pub mining_server: Option<StratumServerConfig>,
|
|
||||||
/// Logging config
|
/// Logging config
|
||||||
pub logging: Option<LoggingConfig>,
|
pub logging: Option<LoggingConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Wallet config. May eventually need to be moved to its own thing. Or not.
|
/// Wallet should be split into a separate configuration file
|
||||||
/// Depends on whether we end up starting the wallet in its own process but
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
/// with the same lifecycle as the server.
|
pub struct GlobalWalletConfig {
|
||||||
|
/// Keep track of the file we've read
|
||||||
|
pub config_file_path: Option<PathBuf>,
|
||||||
|
/// Wallet members
|
||||||
|
pub members: Option<GlobalWalletConfigMembers>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wallet internal members
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct GlobalWalletConfigMembers {
|
||||||
|
/// Wallet configuration
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub wallet: WalletConfig,
|
pub wallet: WalletConfig,
|
||||||
|
/// Logging config
|
||||||
|
pub logging: Option<LoggingConfig>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#[macro_use]
|
|
||||||
extern crate pretty_assertions;
|
|
||||||
extern crate grin_config as config;
|
|
||||||
|
|
||||||
use config::GlobalConfig;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn file_config_equal_to_defaults() {
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
183
grin.toml
183
grin.toml
|
@ -1,183 +0,0 @@
|
||||||
# Sample Server Configuration File for Grin
|
|
||||||
#
|
|
||||||
# When running the grin executable without specifying any command line
|
|
||||||
# arguments, it will look for this file in three places, in the following
|
|
||||||
# order:
|
|
||||||
#
|
|
||||||
# -The working directory
|
|
||||||
# -The directory in which the executable resides
|
|
||||||
# -[user home]/.grin
|
|
||||||
#
|
|
||||||
|
|
||||||
#########################################
|
|
||||||
### SERVER CONFIGURATION ###
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
#Server connection details
|
|
||||||
[server]
|
|
||||||
|
|
||||||
#the address on which services will listen, e.g. Transaction Pool
|
|
||||||
|
|
||||||
api_http_addr = "127.0.0.1:13413"
|
|
||||||
|
|
||||||
#the directory, relative to current, in which the grin blockchain
|
|
||||||
#is stored
|
|
||||||
|
|
||||||
db_root = ".grin"
|
|
||||||
|
|
||||||
#The chain type, which defines the genesis block and the set of cuckoo
|
|
||||||
#parameters used for mining. Can be:
|
|
||||||
#AutomatedTesting - For CI builds and instant blockchain creation
|
|
||||||
#UserTesting - For regular user testing (cuckoo 16)
|
|
||||||
#Testnet1 - Testnet1 genesis block (cuckoo 16)
|
|
||||||
#Testnet2 - Testnet2 genesis block (cuckoo 30)
|
|
||||||
|
|
||||||
chain_type = "Testnet3"
|
|
||||||
|
|
||||||
#The chain validation mode, defines how often (if at all) we
|
|
||||||
#want to run a full chain validation. Can be:
|
|
||||||
#"EveryBlock" - run full chain validation when processing each block (except during sync)
|
|
||||||
#"Disabled" - disable full chain validation (just run regular block validation)
|
|
||||||
#chain_validation_mode = "Disabled"
|
|
||||||
|
|
||||||
#run the node in "full archive" mode (default is fast-sync, pruned node)
|
|
||||||
#archive_mode = false
|
|
||||||
|
|
||||||
#skip waiting for sync on startup, (optional param, mostly for testing)
|
|
||||||
skip_sync_wait = false
|
|
||||||
|
|
||||||
#whether to run the ncurses TUI. Ncurses must be installed and this
|
|
||||||
#will also disable logging to stdout
|
|
||||||
run_tui = true
|
|
||||||
|
|
||||||
#Whether to run the wallet listener with the server by default
|
|
||||||
run_wallet_listener = true
|
|
||||||
|
|
||||||
# Whether to run the web-wallet API (will only run on localhost)
|
|
||||||
# grin wallet web will run this automatically, so this should
|
|
||||||
# only be set to true for test/development purposes
|
|
||||||
run_wallet_owner_api = false
|
|
||||||
|
|
||||||
#Whether to run a test miner. This is only for developer testing (chaintype
|
|
||||||
#usertesting) at cuckoo 16, and will only mine into the default wallet port.
|
|
||||||
#real mining should use the standalone grin-miner
|
|
||||||
run_test_miner = false
|
|
||||||
|
|
||||||
#test miner wallet URL (burns if this doesn't exist)
|
|
||||||
#test_miner_wallet_url = "http://127.0.0.1:13415"
|
|
||||||
|
|
||||||
[server.dandelion_config]
|
|
||||||
#dandelion relay time (choose new relay peer every n secs)
|
|
||||||
relay_secs = 600
|
|
||||||
|
|
||||||
#fluff and broadcast after embargo expires if tx not seen on network
|
|
||||||
embargo_secs = 180
|
|
||||||
|
|
||||||
#run dandelion stem/fluff processing every n secs (stem tx aggregation in this window)
|
|
||||||
patience_secs = 10
|
|
||||||
|
|
||||||
#dandelion stem probability (stem 90% of the time, fluff 10% of the time)
|
|
||||||
stem_probability = 90
|
|
||||||
|
|
||||||
#The P2P server details (i.e. the server that communicates with other
|
|
||||||
#grin server nodes
|
|
||||||
[server.p2p_config]
|
|
||||||
|
|
||||||
host = "0.0.0.0"
|
|
||||||
port = 13414
|
|
||||||
|
|
||||||
#How to seed this server, can be None, List, WebStatic or DNSSeed
|
|
||||||
#
|
|
||||||
#seeding_type = "None"
|
|
||||||
|
|
||||||
#If seeding_type = List, the list of peers to connect to.
|
|
||||||
#
|
|
||||||
#seeds = ["192.168.0.1:13414","192.168.0.2:13414"]
|
|
||||||
|
|
||||||
#7 = Bit flags for FULL_NODE, this structure needs to be changed
|
|
||||||
#internally to make it more configurable
|
|
||||||
capabilities = [7]
|
|
||||||
|
|
||||||
#hardcoded peer lists for allow/deny
|
|
||||||
#will *only* connect to peers in allow list
|
|
||||||
#peers_allow = ["192.168.0.1:13414", "192.168.0.2:13414"]
|
|
||||||
#will *never* connect to peers in deny list
|
|
||||||
#peers_deny = ["192.168.0.3:13414", "192.168.0.4:13414"]
|
|
||||||
#a list of preferred peers to connect to
|
|
||||||
#peers_preferred = ["192.168.0.1:13414","192.168.0.2:13414"]
|
|
||||||
|
|
||||||
#how long a banned peer should stay banned
|
|
||||||
#ban_window = 10800
|
|
||||||
|
|
||||||
#maximum number of peers
|
|
||||||
#peer_max_count = 25
|
|
||||||
|
|
||||||
#preferred minimum number of peers (we'll actively keep trying to add peers
|
|
||||||
#until we get to at least this number
|
|
||||||
#peer_min_preferred_count = 8
|
|
||||||
|
|
||||||
###########################################
|
|
||||||
### STRATUM MINING SERVER CONFIGURATION ###
|
|
||||||
###########################################
|
|
||||||
[mining_server]
|
|
||||||
|
|
||||||
#flag whether stratum server is enabled
|
|
||||||
enable_stratum_server = true
|
|
||||||
|
|
||||||
#what port and address for the stratum server to listen on
|
|
||||||
stratum_server_addr = "127.0.0.1:13416"
|
|
||||||
|
|
||||||
#The amount of time, in seconds, to attempt to mine on a particular
|
|
||||||
#header before stopping and re-collecting transactions from the pool
|
|
||||||
attempt_time_per_block = 15
|
|
||||||
|
|
||||||
#The minimum acceptable share difficulty to request from miners
|
|
||||||
minimum_share_difficulty = 1
|
|
||||||
|
|
||||||
#the wallet receiver to which coinbase rewards will be sent
|
|
||||||
wallet_listener_url = "http://127.0.0.1:13415"
|
|
||||||
|
|
||||||
#whether to ignore the reward (mostly for testing)
|
|
||||||
burn_reward = false
|
|
||||||
|
|
||||||
#########################################
|
|
||||||
### WALLET CONFIGURATION ###
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
[wallet]
|
|
||||||
|
|
||||||
# Host IP for wallet listener, change to "0.0.0.0" to receive grins
|
|
||||||
api_listen_interface = "127.0.0.1"
|
|
||||||
|
|
||||||
# Port for wallet listener
|
|
||||||
api_listen_port = 13415
|
|
||||||
|
|
||||||
# Where the wallet should find a running node
|
|
||||||
check_node_api_http_addr = "http://127.0.0.1:13413"
|
|
||||||
|
|
||||||
# Where to find wallet files (seed, data, etc)
|
|
||||||
data_file_dir = "."
|
|
||||||
|
|
||||||
#########################################
|
|
||||||
### LOGGING CONFIGURATION ###
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
[logging]
|
|
||||||
|
|
||||||
# Whether to log to stdout
|
|
||||||
log_to_stdout = true
|
|
||||||
|
|
||||||
# Log level for stdout: Critical, Error, Warning, Info, Debug, Trace
|
|
||||||
stdout_log_level = "Warning"
|
|
||||||
|
|
||||||
# Whether to log to a file
|
|
||||||
log_to_file = true
|
|
||||||
|
|
||||||
# Log level for file: Critical, Error, Warning, Info, Debug, Trace
|
|
||||||
file_log_level = "Debug"
|
|
||||||
|
|
||||||
# Log file path
|
|
||||||
log_file_path = "grin.log"
|
|
||||||
|
|
||||||
# Whether to append to the log file (true), or replace it on every run (false)
|
|
||||||
log_file_append = true
|
|
|
@ -142,7 +142,7 @@ impl Default for P2PConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note certain fields are options just so they don't have to be
|
/// Note certain fields are options just so they don't have to be
|
||||||
/// included in grin.toml, but we don't want them to ever return none
|
/// included in grin-server.toml, but we don't want them to ever return none
|
||||||
impl P2PConfig {
|
impl P2PConfig {
|
||||||
/// return ban window
|
/// return ban window
|
||||||
pub fn ban_window(&self) -> i64 {
|
pub fn ban_window(&self) -> i64 {
|
||||||
|
|
|
@ -201,8 +201,8 @@ impl Default for StratumStats {
|
||||||
is_running: false,
|
is_running: false,
|
||||||
num_workers: 0,
|
num_workers: 0,
|
||||||
block_height: 0,
|
block_height: 0,
|
||||||
network_difficulty: 0,
|
network_difficulty: 1000,
|
||||||
cuckoo_size: 0,
|
cuckoo_size: 30,
|
||||||
worker_stats: Vec::new(),
|
worker_stats: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,26 +117,12 @@ pub struct ServerConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub chain_type: ChainTypes,
|
pub chain_type: ChainTypes,
|
||||||
|
|
||||||
/// Whether this node is a full archival node or a fast-sync, pruned node
|
|
||||||
pub archive_mode: Option<bool>,
|
|
||||||
|
|
||||||
/// Automatically run full chain validation during normal block processing?
|
/// Automatically run full chain validation during normal block processing?
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub chain_validation_mode: ChainValidationMode,
|
pub chain_validation_mode: ChainValidationMode,
|
||||||
|
|
||||||
/// Configuration for the peer-to-peer server
|
/// Whether this node is a full archival node or a fast-sync, pruned node
|
||||||
pub p2p_config: p2p::P2PConfig,
|
pub archive_mode: Option<bool>,
|
||||||
|
|
||||||
/// Configuration for the mining daemon
|
|
||||||
pub stratum_mining_config: Option<StratumServerConfig>,
|
|
||||||
|
|
||||||
/// Transaction pool configuration
|
|
||||||
#[serde(default)]
|
|
||||||
pub pool_config: pool::PoolConfig,
|
|
||||||
|
|
||||||
/// Dandelion configuration
|
|
||||||
#[serde(default)]
|
|
||||||
pub dandelion_config: pool::DandelionConfig,
|
|
||||||
|
|
||||||
/// Whether to skip the sync timeout on startup
|
/// Whether to skip the sync timeout on startup
|
||||||
/// (To assist testing on solo chains)
|
/// (To assist testing on solo chains)
|
||||||
|
@ -160,23 +146,38 @@ pub struct ServerConfig {
|
||||||
|
|
||||||
/// Test miner wallet URL
|
/// Test miner wallet URL
|
||||||
pub test_miner_wallet_url: Option<String>,
|
pub test_miner_wallet_url: Option<String>,
|
||||||
|
|
||||||
|
/// Configuration for the peer-to-peer server
|
||||||
|
pub p2p_config: p2p::P2PConfig,
|
||||||
|
|
||||||
|
/// Transaction pool configuration
|
||||||
|
#[serde(default)]
|
||||||
|
pub pool_config: pool::PoolConfig,
|
||||||
|
|
||||||
|
/// Dandelion configuration
|
||||||
|
#[serde(default)]
|
||||||
|
pub dandelion_config: pool::DandelionConfig,
|
||||||
|
|
||||||
|
/// Configuration for the mining daemon
|
||||||
|
#[serde(default)]
|
||||||
|
pub stratum_mining_config: Option<StratumServerConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
fn default() -> ServerConfig {
|
fn default() -> ServerConfig {
|
||||||
ServerConfig {
|
ServerConfig {
|
||||||
db_root: ".grin".to_string(),
|
db_root: "grin_chain".to_string(),
|
||||||
api_http_addr: "127.0.0.1:13413".to_string(),
|
api_http_addr: "127.0.0.1:13413".to_string(),
|
||||||
p2p_config: p2p::P2PConfig::default(),
|
p2p_config: p2p::P2PConfig::default(),
|
||||||
dandelion_config: pool::DandelionConfig::default(),
|
dandelion_config: pool::DandelionConfig::default(),
|
||||||
stratum_mining_config: Some(StratumServerConfig::default()),
|
stratum_mining_config: Some(StratumServerConfig::default()),
|
||||||
chain_type: ChainTypes::default(),
|
chain_type: ChainTypes::default(),
|
||||||
archive_mode: None,
|
archive_mode: Some(false),
|
||||||
chain_validation_mode: ChainValidationMode::default(),
|
chain_validation_mode: ChainValidationMode::default(),
|
||||||
pool_config: pool::PoolConfig::default(),
|
pool_config: pool::PoolConfig::default(),
|
||||||
skip_sync_wait: Some(false),
|
skip_sync_wait: Some(false),
|
||||||
run_tui: Some(true),
|
run_tui: Some(true),
|
||||||
run_wallet_listener: Some(true),
|
run_wallet_listener: Some(false),
|
||||||
run_wallet_owner_api: Some(false),
|
run_wallet_owner_api: Some(false),
|
||||||
use_db_wallet: None,
|
use_db_wallet: None,
|
||||||
run_test_miner: Some(false),
|
run_test_miner: Some(false),
|
||||||
|
@ -217,7 +218,7 @@ impl Default for StratumServerConfig {
|
||||||
burn_reward: false,
|
burn_reward: false,
|
||||||
attempt_time_per_block: 15,
|
attempt_time_per_block: 15,
|
||||||
minimum_share_difficulty: 1,
|
minimum_share_difficulty: 1,
|
||||||
enable_stratum_server: Some(true),
|
enable_stratum_server: Some(false),
|
||||||
stratum_server_addr: Some("127.0.0.1:13416".to_string()),
|
stratum_server_addr: Some("127.0.0.1:13416".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,19 +65,21 @@ impl Server {
|
||||||
where
|
where
|
||||||
F: FnMut(Arc<Server>),
|
F: FnMut(Arc<Server>),
|
||||||
{
|
{
|
||||||
let mut mining_config = config.stratum_mining_config.clone();
|
let mining_config = config.stratum_mining_config.clone();
|
||||||
let enable_test_miner = config.run_test_miner;
|
let enable_test_miner = config.run_test_miner;
|
||||||
let test_miner_wallet_url = config.test_miner_wallet_url.clone();
|
let test_miner_wallet_url = config.test_miner_wallet_url.clone();
|
||||||
let serv = Arc::new(Server::new(config)?);
|
let serv = Arc::new(Server::new(config)?);
|
||||||
|
|
||||||
let enable_stratum_server = mining_config.as_mut().unwrap().enable_stratum_server;
|
if let Some(c) = mining_config {
|
||||||
|
let enable_stratum_server = c.enable_stratum_server;
|
||||||
if let Some(s) = enable_stratum_server {
|
if let Some(s) = enable_stratum_server {
|
||||||
if s {
|
if s {
|
||||||
{
|
{
|
||||||
let mut stratum_stats = serv.state_info.stratum_stats.write().unwrap();
|
let mut stratum_stats = serv.state_info.stratum_stats.write().unwrap();
|
||||||
stratum_stats.is_enabled = true;
|
stratum_stats.is_enabled = true;
|
||||||
}
|
}
|
||||||
serv.start_stratum_server(mining_config.clone().unwrap());
|
serv.start_stratum_server(c.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
71
src/bin/cmd/config.rs
Normal file
71
src/bin/cmd/config.rs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2018 The Grin Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/// Grin configuation file output command
|
||||||
|
use config::{GlobalConfig, GlobalWalletConfig};
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
/// Create a config file in the current directory
|
||||||
|
pub fn config_command_server(file_name: &str) {
|
||||||
|
let mut default_config = GlobalConfig::default();
|
||||||
|
let current_dir = env::current_dir().unwrap_or_else(|e| {
|
||||||
|
panic!("Error creating config file: {}", e);
|
||||||
|
});
|
||||||
|
let mut config_file_name = current_dir.clone();
|
||||||
|
config_file_name.push(file_name);
|
||||||
|
if config_file_name.exists() {
|
||||||
|
panic!(
|
||||||
|
"{} already exists in the current directory. Please remove it first",
|
||||||
|
file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default_config.update_paths(¤t_dir);
|
||||||
|
default_config
|
||||||
|
.write_to_file(config_file_name.to_str().unwrap())
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
panic!("Error creating config file: {}", e);
|
||||||
|
});
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{} file configured and created in current directory",
|
||||||
|
file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a config file in the current directory
|
||||||
|
pub fn config_command_wallet(file_name: &str) {
|
||||||
|
let mut default_config = GlobalWalletConfig::default();
|
||||||
|
let current_dir = env::current_dir().unwrap_or_else(|e| {
|
||||||
|
panic!("Error creating config file: {}", e);
|
||||||
|
});
|
||||||
|
let mut config_file_name = current_dir.clone();
|
||||||
|
config_file_name.push(file_name);
|
||||||
|
if config_file_name.exists() {
|
||||||
|
panic!(
|
||||||
|
"{} already exists in the target directory. Please remove it first",
|
||||||
|
file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default_config.update_paths(¤t_dir);
|
||||||
|
default_config
|
||||||
|
.write_to_file(config_file_name.to_str().unwrap())
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
panic!("Error creating config file: {}", e);
|
||||||
|
});
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"File {} configured and created",
|
||||||
|
config_file_name.to_str().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
|
@ -13,9 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
|
mod config;
|
||||||
mod server;
|
mod server;
|
||||||
mod wallet;
|
mod wallet;
|
||||||
|
|
||||||
pub use self::client::client_command;
|
pub use self::client::client_command;
|
||||||
|
pub use self::config::{config_command_server, config_command_wallet};
|
||||||
pub use self::server::server_command;
|
pub use self::server::server_command;
|
||||||
pub use self::wallet::wallet_command;
|
pub use self::wallet::{seed_exists, wallet_command};
|
||||||
|
|
|
@ -123,7 +123,7 @@ pub fn server_command(server_args: Option<&ArgMatches>, mut global_config: Globa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(true) = server_config.run_wallet_listener {
|
/*if let Some(true) = server_config.run_wallet_listener {
|
||||||
let mut wallet_config = global_config.members.as_ref().unwrap().wallet.clone();
|
let mut wallet_config = global_config.members.as_ref().unwrap().wallet.clone();
|
||||||
wallet::init_wallet_seed(wallet_config.clone());
|
wallet::init_wallet_seed(wallet_config.clone());
|
||||||
let wallet = wallet::instantiate_wallet(wallet_config.clone(), "");
|
let wallet = wallet::instantiate_wallet(wallet_config.clone(), "");
|
||||||
|
@ -155,7 +155,7 @@ pub fn server_command(server_args: Option<&ArgMatches>, mut global_config: Globa
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// start the server in the different run modes (interactive or daemon)
|
// start the server in the different run modes (interactive or daemon)
|
||||||
if let Some(a) = server_args {
|
if let Some(a) = server_args {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
/// Wallet commands processing
|
/// Wallet commands processing
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -20,7 +21,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
|
||||||
use config::GlobalConfig;
|
use config::GlobalWalletConfig;
|
||||||
use core::core;
|
use core::core;
|
||||||
use grin_wallet::{self, controller, display, libwallet};
|
use grin_wallet::{self, controller, display, libwallet};
|
||||||
use grin_wallet::{HTTPWalletClient, LMDBBackend, WalletConfig, WalletInst, WalletSeed};
|
use grin_wallet::{HTTPWalletClient, LMDBBackend, WalletConfig, WalletInst, WalletSeed};
|
||||||
|
@ -28,12 +29,22 @@ use keychain;
|
||||||
use servers::start_webwallet_server;
|
use servers::start_webwallet_server;
|
||||||
use util::LOGGER;
|
use util::LOGGER;
|
||||||
|
|
||||||
pub fn init_wallet_seed(wallet_config: WalletConfig) {
|
pub fn _init_wallet_seed(wallet_config: WalletConfig) {
|
||||||
if let Err(_) = WalletSeed::from_file(&wallet_config) {
|
if let Err(_) = WalletSeed::from_file(&wallet_config) {
|
||||||
WalletSeed::init_file(&wallet_config).expect("Failed to create wallet seed file.");
|
WalletSeed::init_file(&wallet_config).expect("Failed to create wallet seed file.");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn seed_exists(wallet_config: WalletConfig) -> bool {
|
||||||
|
let mut data_file_dir = PathBuf::new();
|
||||||
|
data_file_dir.push(wallet_config.data_file_dir);
|
||||||
|
data_file_dir.push(grin_wallet::SEED_FILE);
|
||||||
|
if data_file_dir.exists() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn instantiate_wallet(
|
pub fn instantiate_wallet(
|
||||||
wallet_config: WalletConfig,
|
wallet_config: WalletConfig,
|
||||||
passphrase: &str,
|
passphrase: &str,
|
||||||
|
@ -49,7 +60,7 @@ pub fn instantiate_wallet(
|
||||||
warn!(LOGGER, "Migration successful. Using LMDB Wallet backend");
|
warn!(LOGGER, "Migration successful. Using LMDB Wallet backend");
|
||||||
}
|
}
|
||||||
warn!(LOGGER, "Please check the results of the migration process using `grin wallet info` and `grin wallet outputs`");
|
warn!(LOGGER, "Please check the results of the migration process using `grin wallet info` and `grin wallet outputs`");
|
||||||
warn!(LOGGER, "If anything went wrong, you can try again by deleting the `wallet_data` directory and running a wallet command");
|
warn!(LOGGER, "If anything went wrong, you can try again by deleting the `db` directory and running a wallet command");
|
||||||
warn!(LOGGER, "If all is okay, you can move/backup/delete all files in the wallet directory EXCEPT FOR wallet.seed");
|
warn!(LOGGER, "If all is okay, you can move/backup/delete all files in the wallet directory EXCEPT FOR wallet.seed");
|
||||||
}
|
}
|
||||||
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr);
|
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr);
|
||||||
|
@ -63,9 +74,9 @@ pub fn instantiate_wallet(
|
||||||
Box::new(db_wallet)
|
Box::new(db_wallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||||
// just get defaults from the global config
|
// just get defaults from the global config
|
||||||
let mut wallet_config = global_config.members.unwrap().wallet;
|
let mut wallet_config = config.members.unwrap().wallet;
|
||||||
|
|
||||||
if wallet_args.is_present("external") {
|
if wallet_args.is_present("external") {
|
||||||
wallet_config.api_listen_interface = "0.0.0.0".to_string();
|
wallet_config.api_listen_interface = "0.0.0.0".to_string();
|
||||||
|
|
131
src/bin/grin.rs
131
src/bin/grin.rs
|
@ -41,7 +41,7 @@ pub mod tui;
|
||||||
|
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::{App, Arg, SubCommand};
|
||||||
|
|
||||||
use config::GlobalConfig;
|
use config::config::{SERVER_CONFIG_FILE_NAME, WALLET_CONFIG_FILE_NAME};
|
||||||
use core::global;
|
use core::global;
|
||||||
use util::{init_logger, LOGGER};
|
use util::{init_logger, LOGGER};
|
||||||
|
|
||||||
|
@ -81,10 +81,14 @@ fn main() {
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.author("The Grin Team")
|
.author("The Grin Team")
|
||||||
.about("Lightweight implementation of the MimbleWimble protocol.")
|
.about("Lightweight implementation of the MimbleWimble protocol.")
|
||||||
|
|
||||||
// specification of all the server commands and options
|
// specification of all the server commands and options
|
||||||
.subcommand(SubCommand::with_name("server")
|
.subcommand(SubCommand::with_name("server")
|
||||||
.about("Control the Grin server")
|
.about("Control the Grin server")
|
||||||
|
.arg(Arg::with_name("config_file")
|
||||||
|
.short("c")
|
||||||
|
.long("config_file")
|
||||||
|
.help("Path to a grin-server.toml configuration file")
|
||||||
|
.takes_value(true))
|
||||||
.arg(Arg::with_name("port")
|
.arg(Arg::with_name("port")
|
||||||
.short("p")
|
.short("p")
|
||||||
.long("port")
|
.long("port")
|
||||||
|
@ -105,6 +109,8 @@ fn main() {
|
||||||
.long("wallet_url")
|
.long("wallet_url")
|
||||||
.help("The wallet listener to which mining rewards will be sent")
|
.help("The wallet listener to which mining rewards will be sent")
|
||||||
.takes_value(true))
|
.takes_value(true))
|
||||||
|
.subcommand(SubCommand::with_name("config")
|
||||||
|
.about("Generate a configuration grin-server.toml file in the current directory"))
|
||||||
.subcommand(SubCommand::with_name("start")
|
.subcommand(SubCommand::with_name("start")
|
||||||
.about("Start the Grin server as a daemon"))
|
.about("Start the Grin server as a daemon"))
|
||||||
.subcommand(SubCommand::with_name("stop")
|
.subcommand(SubCommand::with_name("stop")
|
||||||
|
@ -274,85 +280,114 @@ fn main() {
|
||||||
.about("basic wallet contents summary"))
|
.about("basic wallet contents summary"))
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("init")
|
.subcommand(SubCommand::with_name("init")
|
||||||
.about("Initialize a new wallet seed file and database."))
|
.about("Initialize a new wallet seed file and database.")
|
||||||
|
.arg(Arg::with_name("here")
|
||||||
|
.short("h")
|
||||||
|
.long("here")
|
||||||
|
.help("Create wallet files in the current directory instead of the default ~/.grin directory")
|
||||||
|
.takes_value(false)))
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("restore")
|
.subcommand(SubCommand::with_name("restore")
|
||||||
.about("Attempt to restore wallet contents from the chain using seed and password. \
|
.about("Attempt to restore wallet contents from the chain using seed and password. \
|
||||||
NOTE: Backup wallet.* and run `wallet listen` before running restore.")))
|
NOTE: Backup wallet.* and run `wallet listen` before running restore.")))
|
||||||
|
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
let mut wallet_config = None;
|
||||||
|
let mut node_config = None;
|
||||||
|
|
||||||
// load a global config object,
|
// Deal with configuration file creation
|
||||||
// then modify that object with any switches
|
match args.subcommand() {
|
||||||
// found so that the switches override the
|
("server", Some(server_args)) => {
|
||||||
// global config file
|
// If it's just a server config command, do it and exit
|
||||||
|
if let ("config", Some(_)) = server_args.subcommand() {
|
||||||
// This will return a global config object,
|
cmd::config_command_server(SERVER_CONFIG_FILE_NAME);
|
||||||
// which will either contain defaults for all // of the config structures or a
|
return;
|
||||||
// configuration
|
|
||||||
// read from a config file
|
|
||||||
|
|
||||||
let mut global_config = GlobalConfig::new(None).unwrap_or_else(|e| {
|
|
||||||
panic!("Error parsing config file: {}", e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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(
|
("wallet", Some(wallet_args)) => {
|
||||||
global_config
|
// wallet init command should spit out its config file then continue
|
||||||
.members
|
// (if desired)
|
||||||
.as_mut()
|
if let ("init", Some(init_args)) = wallet_args.subcommand() {
|
||||||
.unwrap()
|
if init_args.is_present("here") {
|
||||||
.server
|
cmd::config_command_wallet(WALLET_CONFIG_FILE_NAME);
|
||||||
.clone()
|
}
|
||||||
.chain_type,
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match args.subcommand() {
|
||||||
|
// If it's a wallet command, try and load a wallet config file
|
||||||
|
("wallet", Some(wallet_args)) => {
|
||||||
|
let mut w = config::initial_setup_wallet().unwrap_or_else(|e| {
|
||||||
|
panic!("Error loading wallet configuration: {}", e);
|
||||||
|
});
|
||||||
|
if !cmd::seed_exists(w.members.as_ref().unwrap().wallet.clone()) {
|
||||||
|
if let ("init", Some(_)) = wallet_args.subcommand() {
|
||||||
|
} else {
|
||||||
|
println!("Wallet seed file doesn't exist. Run `grin wallet -p [password] init` first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut l = w.members.as_mut().unwrap().logging.clone().unwrap();
|
||||||
|
l.tui_running = Some(false);
|
||||||
|
init_logger(Some(l));
|
||||||
|
warn!(
|
||||||
|
LOGGER,
|
||||||
|
"Using wallet configuration file at {}",
|
||||||
|
w.config_file_path.as_ref().unwrap().to_str().unwrap()
|
||||||
);
|
);
|
||||||
|
wallet_config = Some(w);
|
||||||
log_build_info();
|
}
|
||||||
|
// Otherwise load up the node config as usual
|
||||||
if let Some(file_path) = &global_config.config_file_path {
|
_ => {
|
||||||
|
let mut s = config::initial_setup_server().unwrap_or_else(|e| {
|
||||||
|
panic!("Error loading server configuration: {}", e);
|
||||||
|
});
|
||||||
|
let mut l = s.members.as_mut().unwrap().logging.clone().unwrap();
|
||||||
|
let run_tui = s.members.as_mut().unwrap().server.run_tui;
|
||||||
|
if let Some(true) = run_tui {
|
||||||
|
l.log_to_stdout = false;
|
||||||
|
l.tui_running = Some(true);
|
||||||
|
}
|
||||||
|
init_logger(Some(l));
|
||||||
|
global::set_mining_mode(s.members.as_mut().unwrap().server.clone().chain_type);
|
||||||
|
if let Some(file_path) = &s.config_file_path {
|
||||||
info!(
|
info!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"Found configuration file at {}",
|
"Using configuration file at {}",
|
||||||
file_path.to_str().unwrap()
|
file_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
info!(LOGGER, "configuration file not found, using default");
|
info!(LOGGER, "Node configuration file not found, using default");
|
||||||
}
|
}
|
||||||
|
node_config = Some(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_build_info();
|
||||||
|
|
||||||
match args.subcommand() {
|
match args.subcommand() {
|
||||||
// server commands and options
|
// server commands and options
|
||||||
("server", Some(server_args)) => {
|
("server", Some(server_args)) => {
|
||||||
cmd::server_command(Some(server_args), global_config);
|
cmd::server_command(Some(server_args), node_config.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// client commands and options
|
// client commands and options
|
||||||
("client", Some(client_args)) => {
|
("client", Some(client_args)) => {
|
||||||
cmd::client_command(client_args, global_config);
|
cmd::client_command(client_args, node_config.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// client commands and options
|
// client commands and options
|
||||||
("wallet", Some(wallet_args)) => {
|
("wallet", Some(wallet_args)) => {
|
||||||
cmd::wallet_command(wallet_args, global_config);
|
cmd::wallet_command(wallet_args, wallet_config.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing is specified, try to just use the config file instead
|
// If nothing is specified, try to just use the config file instead
|
||||||
// this could possibly become the way to configure most things
|
// this could possibly become the way to configure most things
|
||||||
// with most command line options being phased out
|
// with most command line options being phased out
|
||||||
_ => {
|
_ => {
|
||||||
cmd::server_command(None, global_config);
|
cmd::server_command(None, node_config.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ use store::{self, to_key};
|
||||||
const DETAIL_FILE: &'static str = "wallet.det";
|
const DETAIL_FILE: &'static str = "wallet.det";
|
||||||
const DAT_FILE: &'static str = "wallet.dat";
|
const DAT_FILE: &'static str = "wallet.dat";
|
||||||
const SEED_FILE: &'static str = "wallet.seed";
|
const SEED_FILE: &'static str = "wallet.seed";
|
||||||
const DB_DIR: &'static str = "wallet_data";
|
const DB_DIR: &'static str = "db";
|
||||||
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
||||||
const DERIV_PREFIX: u8 = 'd' as u8;
|
const DERIV_PREFIX: u8 = 'd' as u8;
|
||||||
const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8;
|
const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8;
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub use libwallet::types::{
|
||||||
BlockFees, CbData, WalletBackend, WalletClient, WalletInfo, WalletInst,
|
BlockFees, CbData, WalletBackend, WalletClient, WalletInfo, WalletInst,
|
||||||
};
|
};
|
||||||
pub use lmdb_wallet::{wallet_db_exists, LMDBBackend};
|
pub use lmdb_wallet::{wallet_db_exists, LMDBBackend};
|
||||||
pub use types::{WalletConfig, WalletSeed};
|
pub use types::{WalletConfig, WalletSeed, SEED_FILE};
|
||||||
|
|
||||||
// temporary
|
// temporary
|
||||||
pub use db_migrate::{migrate, needs_migrate};
|
pub use db_migrate::{migrate, needs_migrate};
|
||||||
|
|
|
@ -159,7 +159,7 @@ where
|
||||||
if !is_empty {
|
if !is_empty {
|
||||||
error!(
|
error!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"Not restoring. Please back up and remove existing wallet_data directory first."
|
"Not restoring. Please back up and remove existing db directory first."
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ use libwallet::{internal, Error, ErrorKind};
|
||||||
use types::{WalletConfig, WalletSeed};
|
use types::{WalletConfig, WalletSeed};
|
||||||
use util::secp::pedersen;
|
use util::secp::pedersen;
|
||||||
|
|
||||||
pub const DB_DIR: &'static str = "wallet_data";
|
pub const DB_DIR: &'static str = "db";
|
||||||
|
|
||||||
const COMMITMENT_PREFIX: u8 = 'C' as u8;
|
const COMMITMENT_PREFIX: u8 = 'C' as u8;
|
||||||
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
||||||
|
|
Loading…
Reference in a new issue