diff --git a/config/src/comments.rs b/config/src/comments.rs index 0bb5680e5f..63a26f1d96 100644 --- a/config/src/comments.rs +++ b/config/src/comments.rs @@ -258,41 +258,71 @@ fn comments() -> HashMap { ); retval.insert( - "[server.p2p_config.capabilities]".to_string(), - "#If the seeding type is List, the list of peers to connect to can -#be specified as follows: -#seeds = [\"192.168.0.1:3414\",\"192.168.0.2:3414\"] - -#hardcoded peer lists for allow/deny -#will *only* connect to peers in allow list -#peers_allow = [\"192.168.0.1:3414\", \"192.168.0.2:3414\"] -#will *never* connect to peers in deny list -#peers_deny = [\"192.168.0.3:3414\", \"192.168.0.4:3414\"] -#a list of preferred peers to connect to -#peers_preferred = [\"192.168.0.1:3414\",\"192.168.0.2:3414\"] - + "ban_window".to_string(), + " #how long a banned peer should stay banned -#ban_window = 10800 +" + .to_string(), + ); + retval.insert( + "peer_max_inbound_count".to_string(), + " #maximum number of inbound peer connections -#peer_max_inbound_count = 128 +" + .to_string(), + ); + retval.insert( + "peer_max_outbound_count".to_string(), + " #maximum number of outbound peer connections -#peer_max_outbound_count = 8 +" + .to_string(), + ); + retval.insert( + "peer_min_preferred_outbound_count".to_string(), + " #preferred minimum number of outbound peers (we'll actively keep trying to add peers #until we get to at least this number) -#peer_min_preferred_outbound_count = 8 +" + .to_string(), + ); + retval.insert( + "peer_listener_buffer_count".to_string(), + " #amount of incoming connections temporarily allowed to exceed peer_max_inbound_count -#peer_listener_buffer_count = 8 - -# 15 = Bit flags for FULL_NODE -#This structure needs to be changed internally, to make it more configurable +" + .to_string(), + ); + retval.insert( + "dandelion_peer".to_string(), + " # A preferred dandelion_peer, mainly used for testing dandelion -# dandelion_peer = \"10.0.0.1:13144\" +" + .to_string(), + ); + retval.insert( + "capabilities".to_string(), + " +#If the seeding type is List, the list of peers to connect to can +#be specified as follows: +#seeds = [\"192.168.0.1:3414\",\"192.168.0.2:3414\"] + +#hardcoded peer lists for allow/deny +#will *only* connect to peers in allow list +#peers_allow = [\"192.168.0.1:3414\", \"192.168.0.2:3414\"] +#will *never* connect to peers in deny list +#peers_deny = [\"192.168.0.3:3414\", \"192.168.0.4:3414\"] +#a list of preferred peers to connect to +#peers_preferred = [\"192.168.0.1:3414\",\"192.168.0.2:3414\"] + +# 15 = Bit flags for FULL_NODE +#This structure needs to be changed internally, to make it more configurable " .to_string(), ); @@ -477,7 +507,7 @@ fn comments() -> HashMap { } fn get_key(line: &str) -> String { - if line.contains("[") && line.contains("]") { + if line.contains("[") && line.contains("]") && !line.contains("=") { return line.to_owned(); } else if line.contains("=") { return line.split("=").collect::>()[0].trim().to_owned(); diff --git a/config/src/config.rs b/config/src/config.rs index 6e5a54669f..07288fcd6d 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -133,6 +133,27 @@ pub fn initial_setup_server(chain_type: &global::ChainTypes) -> Result String { + let lines: Vec<&str> = orig.split("\n").collect(); + let mut out_lines = vec![]; + for l in lines { + // Comment lines with values (not starting by #) that don't define paths + if l.contains("=") && !l.starts_with("#") && !l.contains("root") && !l.contains("path") { + let mut commented = l.to_owned(); + commented.insert_str(0, "#"); + out_lines.push(commented.to_owned()); + } else { + 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() +} + /// Returns the defaults, as strewn throughout the code impl Default for ConfigMembers { fn default() -> ConfigMembers { @@ -297,6 +318,7 @@ impl GlobalConfig { 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 conf_out = comment_values(conf_out); let mut file = File::create(name)?; file.write_all(conf_out.as_bytes())?; Ok(()) diff --git a/p2p/src/peers.rs b/p2p/src/peers.rs index 8181051287..0a555c1ddf 100644 --- a/p2p/src/peers.rs +++ b/p2p/src/peers.rs @@ -515,7 +515,7 @@ impl Peers { /// We have enough outbound connected peers pub fn enough_outbound_peers(&self) -> bool { - self.peer_outbound_count() >= self.config.peer_min_preferred_outbound_count() + self.peer_outbound_count() >= self.config.peer_min_preferred_outbound_count } /// Removes those peers that seem to have expired diff --git a/p2p/src/serv.rs b/p2p/src/serv.rs index 6629604b00..504d96bdce 100644 --- a/p2p/src/serv.rs +++ b/p2p/src/serv.rs @@ -213,7 +213,7 @@ impl Server { /// duplicate connections, malicious or not. fn check_undesirable(&self, stream: &TcpStream) -> bool { if self.peers.peer_inbound_count() - >= self.config.peer_max_inbound_count() + self.config.peer_listener_buffer_count() + >= self.config.peer_max_inbound_count + self.config.peer_listener_buffer_count { debug!("Accepting new connection will exceed peer limit, refusing connection."); return true; diff --git a/p2p/src/types.rs b/p2p/src/types.rs index f9a5f40bec..a306b6e1b5 100644 --- a/p2p/src/types.rs +++ b/p2p/src/types.rs @@ -13,6 +13,8 @@ // limitations under the License. use crate::util::RwLock; +use serde::ser::{Serialize, Serializer}; +use serde::{Deserialize, Deserializer}; use std::convert::From; use std::fs::File; use std::io::{self, Read}; @@ -61,6 +63,15 @@ const PEER_MIN_PREFERRED_OUTBOUND_COUNT: u32 = 8; /// than allowed by PEER_MAX_INBOUND_COUNT to encourage network bootstrapping. const PEER_LISTENER_BUFFER_COUNT: u32 = 8; +/// Default bind IP address +const P2P_DEFAULT_IP: &str = "0.0.0.0"; + +/// Default port +const P2P_DEFAULT_PORT: u16 = 3414; + +/// Default dandelion peer +const P2P_DEFAULT_DANDELION_PEER: &str = "10.0.0.1:13144"; + #[derive(Debug)] pub enum Error { Serialization(ser::Error), @@ -215,7 +226,9 @@ impl PeerAddr { /// Configuration for the peer-to-peer server. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct P2PConfig { + #[serde(default = "default_p2p_ipaddr")] pub host: IpAddr, + #[serde(default = "default_p2p_port")] pub port: u16, /// Method used to get the list of seed nodes for initial bootstrap. @@ -223,97 +236,111 @@ pub struct P2PConfig { pub seeding_type: Seeding, /// The list of seed nodes, if using Seeding as a seed type + #[serde(default = "default_p2p_seeds")] pub seeds: Option>, - /// Capabilities expose by this node, also conditions which other peers this - /// node will have an affinity toward when connection. - pub capabilities: Capabilities, - + #[serde(default = "default_p2p_peers_allow")] pub peers_allow: Option>, + #[serde(default = "default_p2p_peers_deny")] pub peers_deny: Option>, /// The list of preferred peers that we will try to connect to + #[serde(default = "default_p2p_peers_preferred")] pub peers_preferred: Option>, - pub ban_window: Option, + #[serde(default = "default_p2p_banwindow")] + pub ban_window: i64, - pub peer_max_inbound_count: Option, + #[serde(default = "default_p2p_peer_max_inbound_count")] + pub peer_max_inbound_count: u32, - pub peer_max_outbound_count: Option, + #[serde(default = "default_p2p_peer_max_outbound_count")] + pub peer_max_outbound_count: u32, - pub peer_min_preferred_outbound_count: Option, + #[serde(default = "default_p2p_peer_min_preferred_outbound_count")] + pub peer_min_preferred_outbound_count: u32, - pub peer_listener_buffer_count: Option, + #[serde(default = "default_p2p_peer_listener_buffer_count")] + pub peer_listener_buffer_count: u32, - pub dandelion_peer: Option, + #[serde(default = "default_p2p_dandelion_peer")] + pub dandelion_peer: PeerAddr, + + /// Capabilities expose by this node, also conditions which other peers this + /// node will have an affinity toward when connection. + #[serde(default)] + pub capabilities: Capabilities, } /// Default address for peer-to-peer connections. impl Default for P2PConfig { fn default() -> P2PConfig { - let ipaddr = "0.0.0.0".parse().unwrap(); P2PConfig { - host: ipaddr, - port: 3414, - capabilities: Capabilities::FULL_NODE, + host: default_p2p_ipaddr(), + port: default_p2p_port(), + capabilities: Capabilities::default(), seeding_type: Seeding::default(), - seeds: None, - peers_allow: None, - peers_deny: None, - peers_preferred: None, - ban_window: None, - peer_max_inbound_count: None, - peer_max_outbound_count: None, - peer_min_preferred_outbound_count: None, - peer_listener_buffer_count: None, - dandelion_peer: None, + seeds: default_p2p_seeds(), + peers_allow: default_p2p_peers_allow(), + peers_deny: default_p2p_peers_deny(), + peers_preferred: default_p2p_peers_preferred(), + ban_window: default_p2p_banwindow(), + peer_max_inbound_count: default_p2p_peer_max_inbound_count(), + peer_max_outbound_count: default_p2p_peer_max_outbound_count(), + peer_min_preferred_outbound_count: default_p2p_peer_min_preferred_outbound_count(), + peer_listener_buffer_count: default_p2p_peer_listener_buffer_count(), + dandelion_peer: default_p2p_dandelion_peer(), } } } -/// Note certain fields are options just so they don't have to be -/// included in grin-server.toml, but we don't want them to ever return none -impl P2PConfig { - /// return ban window - pub fn ban_window(&self) -> i64 { - match self.ban_window { - Some(n) => n, - None => BAN_WINDOW, - } - } +fn default_p2p_ipaddr() -> IpAddr { + P2P_DEFAULT_IP.parse().unwrap() +} - /// return maximum inbound peer connections count - pub fn peer_max_inbound_count(&self) -> u32 { - match self.peer_max_inbound_count { - Some(n) => n, - None => PEER_MAX_INBOUND_COUNT, - } - } +fn default_p2p_port() -> u16 { + P2P_DEFAULT_PORT +} - /// return maximum outbound peer connections count - pub fn peer_max_outbound_count(&self) -> u32 { - match self.peer_max_outbound_count { - Some(n) => n, - None => PEER_MAX_OUTBOUND_COUNT, - } - } +fn default_p2p_seeds() -> Option> { + None +} - /// return minimum preferred outbound peer count - pub fn peer_min_preferred_outbound_count(&self) -> u32 { - match self.peer_min_preferred_outbound_count { - Some(n) => n, - None => PEER_MIN_PREFERRED_OUTBOUND_COUNT, - } - } +fn default_p2p_peers_allow() -> Option> { + None +} - /// return peer buffer count for listener - pub fn peer_listener_buffer_count(&self) -> u32 { - match self.peer_listener_buffer_count { - Some(n) => n, - None => PEER_LISTENER_BUFFER_COUNT, - } - } +fn default_p2p_peers_deny() -> Option> { + None +} + +fn default_p2p_peers_preferred() -> Option> { + None +} + +fn default_p2p_banwindow() -> i64 { + BAN_WINDOW +} + +fn default_p2p_peer_max_inbound_count() -> u32 { + PEER_MAX_INBOUND_COUNT +} + +fn default_p2p_peer_max_outbound_count() -> u32 { + PEER_MAX_OUTBOUND_COUNT +} + +fn default_p2p_peer_min_preferred_outbound_count() -> u32 { + PEER_MIN_PREFERRED_OUTBOUND_COUNT +} + +fn default_p2p_peer_listener_buffer_count() -> u32 { + PEER_LISTENER_BUFFER_COUNT +} + +fn default_p2p_dandelion_peer() -> PeerAddr { + PeerAddr(P2P_DEFAULT_DANDELION_PEER.parse().unwrap()) } /// Type of seeding the server will use to find other peers on the network. @@ -337,7 +364,6 @@ impl Default for Seeding { bitflags! { /// Options for what type of interaction a peer supports - #[derive(Serialize, Deserialize)] pub struct Capabilities: u32 { /// We don't know (yet) what the peer can do. const UNKNOWN = 0b00000000; @@ -363,6 +389,34 @@ bitflags! { } } +impl Serialize for Capabilities { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.bits().serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Capabilities { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value = <_ as Deserialize<'de>>::deserialize(deserializer)?; + + Capabilities::from_bits(value).ok_or_else(|| { + serde::de::Error::custom(format!("Invalid bits {:#X} for Capabilities", value)) + }) + } +} + +impl Default for Capabilities { + fn default() -> Capabilities { + Capabilities::FULL_NODE + } +} + // Types of connection enum_from_primitive! { #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] diff --git a/pool/src/types.rs b/pool/src/types.rs index fb8e91a67b..418a53dc1c 100644 --- a/pool/src/types.rs +++ b/pool/src/types.rs @@ -45,6 +45,15 @@ const DANDELION_STEM_PROBABILITY: u8 = 90; /// If set to false we will stem/fluff our txs as per current epoch. const DANDELION_ALWAYS_STEM_OUR_TXS: bool = true; +/// Default Base fee for a transaction to be accepted by the pool +const POOL_ACCEPT_FEE_BASE: u64 = consensus::MILLI_GRIN; + +/// Maximum capacity of the pool in number of transactions +const POOL_MAX_POOL_SIZE: usize = 50_000; + +/// Maximum capacity of the Dandelion stempool in number of transactions +const POOL_MAX_STEMPOOL_SIZE: usize = 50_000; + /// Configuration for "Dandelion". /// Note: shared between p2p and pool. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -135,13 +144,13 @@ impl Default for PoolConfig { } fn default_accept_fee_base() -> u64 { - consensus::MILLI_GRIN + POOL_ACCEPT_FEE_BASE } fn default_max_pool_size() -> usize { - 50_000 + POOL_MAX_POOL_SIZE } fn default_max_stempool_size() -> usize { - 50_000 + POOL_MAX_STEMPOOL_SIZE } fn default_mineable_max_weight() -> usize { global::max_block_weight() diff --git a/servers/src/common/types.rs b/servers/src/common/types.rs index 1f94b2228d..4e007ca5a6 100644 --- a/servers/src/common/types.rs +++ b/servers/src/common/types.rs @@ -29,6 +29,51 @@ use crate::pool; use crate::pool::types::DandelionConfig; use crate::store; +/// Directory under which the rocksdb stores will be created +const SERVER_DB_ROOT: &str = "grin_chain"; + +/// Network address for the Rest API HTTP server. +const SERVER_API_HTTP_ADDR: &str = "127.0.0.1:3413"; + +/// Location of secret for basic auth on Rest API HTTP server. +const SERVER_API_SECRET: &str = ".api_secret"; + +/// Whether this node is a full archival node or a fast-sync, pruned node +const SERVER_ARCHIVE_MODE: bool = false; + +/// Whether to skip the sync timeout on startup (To assist testing on solo chains) +const SERVER_SKIP_SYNC_WAIT: bool = false; + +/// Whether to run the TUI +const SERVER_RUN_TUI: bool = true; + +/// Whether to run the test miner +const SERVER_RUN_TEST_MINER: bool = false; + +/// Run a stratum mining server +const STRATUM_ENABLE_SERVER: bool = false; + +/// The address and port the stratum server must listen on +const STRATUM_SERVER_ADDR: &str = "127.0.0.1:3416"; + +/// How long to wait before stopping the miner, recollecting transactions and starting again +const STRATUM_ATTEMPT_TIME_PER_BLOCK: u32 = 15; + +/// Minimum difficulty for worker shares +const STRATUM_MINIMUM_SHARE_DIFFICULTY: u64 = 1; + +/// Base address to the HTTP wallet receiver +const STRATUM_WALLET_LISTENER_URL: &str = "http://127.0.0.1:3415"; + +/// Attributes the reward to a random private key instead of contacting the wallet receiver +const STRATUM_BURN_REWARD: bool = false; + +/// number of worker threads in the tokio runtime +const WEBHOOKS_NTHREADS: u16 = 4; + +/// timeout in seconds for the http request +const WEBHOOKS_TIMEOUT: u16 = 10; + /// Error type wrapping underlying module errors. #[derive(Debug)] pub enum Error { @@ -140,17 +185,22 @@ impl Default for ChainValidationMode { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ServerConfig { /// Directory under which the rocksdb stores will be created + #[serde(default = "default_server_db_root")] pub db_root: String, /// Network address for the Rest API HTTP server. + #[serde(default = "default_server_api_http_addr")] pub api_http_addr: String, /// Location of secret for basic auth on Rest API HTTP server. + #[serde(default = "default_server_api_secret_path")] pub api_secret_path: Option, /// TLS certificate file + #[serde(default = "default_server_tls_certificate_file")] pub tls_certificate_file: Option, /// TLS certificate private key file + #[serde(default = "default_server_tls_certificate_key")] pub tls_certificate_key: Option, /// Setup the server for tests, testnet or mainnet @@ -162,23 +212,29 @@ pub struct ServerConfig { pub chain_validation_mode: ChainValidationMode, /// Whether this node is a full archival node or a fast-sync, pruned node - pub archive_mode: Option, + #[serde(default = "default_server_archive_mode")] + pub archive_mode: bool, /// Whether to skip the sync timeout on startup /// (To assist testing on solo chains) - pub skip_sync_wait: Option, + #[serde(default = "default_server_skip_sync_wait")] + pub skip_sync_wait: bool, /// Whether to run the TUI /// if enabled, this will disable logging to stdout - pub run_tui: Option, + #[serde(default = "default_server_run_tui")] + pub run_tui: bool, /// Whether to run the test miner (internal, cuckoo 16) - pub run_test_miner: Option, + #[serde(default = "default_server_run_test_miner")] + pub run_test_miner: bool, /// Test miner wallet URL + #[serde(default = "default_server_test_miner_wallet_url")] pub test_miner_wallet_url: Option, /// Configuration for the peer-to-peer server + #[serde(default)] pub p2p_config: p2p::P2PConfig, /// Transaction pool configuration @@ -201,101 +257,191 @@ pub struct ServerConfig { impl Default for ServerConfig { fn default() -> ServerConfig { ServerConfig { - db_root: "grin_chain".to_string(), - api_http_addr: "127.0.0.1:3413".to_string(), - api_secret_path: Some(".api_secret".to_string()), - tls_certificate_file: None, - tls_certificate_key: None, + db_root: default_server_db_root(), + api_http_addr: default_server_api_http_addr(), + api_secret_path: default_server_api_secret_path(), + tls_certificate_file: default_server_tls_certificate_file(), + tls_certificate_key: default_server_tls_certificate_key(), p2p_config: p2p::P2PConfig::default(), dandelion_config: pool::DandelionConfig::default(), stratum_mining_config: Some(StratumServerConfig::default()), chain_type: ChainTypes::default(), - archive_mode: Some(false), + archive_mode: default_server_archive_mode(), chain_validation_mode: ChainValidationMode::default(), pool_config: pool::PoolConfig::default(), - skip_sync_wait: Some(false), - run_tui: Some(true), - run_test_miner: Some(false), - test_miner_wallet_url: None, + skip_sync_wait: default_server_skip_sync_wait(), + run_tui: default_server_run_tui(), + run_test_miner: default_server_run_test_miner(), + test_miner_wallet_url: default_server_test_miner_wallet_url(), webhook_config: WebHooksConfig::default(), } } } +fn default_server_db_root() -> String { + SERVER_DB_ROOT.to_string() +} + +fn default_server_api_http_addr() -> String { + SERVER_API_HTTP_ADDR.to_string() +} + +fn default_server_api_secret_path() -> Option { + Some(SERVER_API_SECRET.to_string()) +} + +fn default_server_tls_certificate_file() -> Option { + None +} + +fn default_server_tls_certificate_key() -> Option { + None +} + +fn default_server_archive_mode() -> bool { + SERVER_ARCHIVE_MODE +} + +fn default_server_skip_sync_wait() -> bool { + SERVER_SKIP_SYNC_WAIT +} + +fn default_server_run_tui() -> bool { + SERVER_RUN_TUI +} + +fn default_server_run_test_miner() -> bool { + SERVER_RUN_TEST_MINER +} + +fn default_server_test_miner_wallet_url() -> Option { + None +} + /// Stratum (Mining server) configuration #[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 + #[serde(default = "default_stratum_enable_stratum_server")] pub enable_stratum_server: Option, /// If enabled, the address and port to listen on + #[serde(default = "default_stratum_server_addr")] pub stratum_server_addr: Option, /// How long to wait before stopping the miner, recollecting transactions /// and starting again + #[serde(default = "default_stratum_attempt_time_per_block")] pub attempt_time_per_block: u32, /// Minimum difficulty for worker shares + #[serde(default = "default_stratum_minimum_share_difficulty")] pub minimum_share_difficulty: u64, /// Base address to the HTTP wallet receiver + #[serde(default = "default_stratum_wallet_listener_url")] pub wallet_listener_url: String, /// Attributes the reward to a random private key instead of contacting the /// wallet receiver. Mostly used for tests. + #[serde(default = "default_stratum_burn_reward")] pub burn_reward: bool, } impl Default for StratumServerConfig { fn default() -> StratumServerConfig { StratumServerConfig { - wallet_listener_url: "http://127.0.0.1:3415".to_string(), - burn_reward: false, - attempt_time_per_block: 15, - minimum_share_difficulty: 1, - enable_stratum_server: Some(false), - stratum_server_addr: Some("127.0.0.1:3416".to_string()), + wallet_listener_url: default_stratum_wallet_listener_url(), + burn_reward: default_stratum_burn_reward(), + attempt_time_per_block: default_stratum_attempt_time_per_block(), + minimum_share_difficulty: default_stratum_minimum_share_difficulty(), + enable_stratum_server: default_stratum_enable_stratum_server(), + stratum_server_addr: default_stratum_server_addr(), } } } +fn default_stratum_enable_stratum_server() -> Option { + Some(STRATUM_ENABLE_SERVER) +} + +fn default_stratum_server_addr() -> Option { + Some(STRATUM_SERVER_ADDR.to_string()) +} + +fn default_stratum_attempt_time_per_block() -> u32 { + STRATUM_ATTEMPT_TIME_PER_BLOCK +} + +fn default_stratum_minimum_share_difficulty() -> u64 { + STRATUM_MINIMUM_SHARE_DIFFICULTY +} + +fn default_stratum_wallet_listener_url() -> String { + STRATUM_WALLET_LISTENER_URL.to_string() +} + +fn default_stratum_burn_reward() -> bool { + STRATUM_BURN_REWARD +} + /// Web hooks configuration #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct WebHooksConfig { /// url to POST transaction data when a new transaction arrives from a peer + #[serde(default = "default_webhooks_tx_received_url")] pub tx_received_url: Option, /// url to POST header data when a new header arrives from a peer + #[serde(default = "default_webhooks_header_received_url")] pub header_received_url: Option, /// url to POST block data when a new block arrives from a peer + #[serde(default = "default_webhooks_block_received_url")] pub block_received_url: Option, /// url to POST block data when a new block is accepted by our node (might be a reorg or a fork) + #[serde(default = "default_webhooks_block_accepted_url")] pub block_accepted_url: Option, /// number of worker threads in the tokio runtime - #[serde(default = "default_nthreads")] + #[serde(default = "default_webhooks_nthreads")] pub nthreads: u16, /// timeout in seconds for the http request - #[serde(default = "default_timeout")] + #[serde(default = "default_webhooks_timeout")] pub timeout: u16, } -fn default_timeout() -> u16 { - 10 +fn default_webhooks_tx_received_url() -> Option { + None +} + +fn default_webhooks_header_received_url() -> Option { + None +} + +fn default_webhooks_block_received_url() -> Option { + None +} + +fn default_webhooks_block_accepted_url() -> Option { + None +} + +fn default_webhooks_nthreads() -> u16 { + WEBHOOKS_NTHREADS } -fn default_nthreads() -> u16 { - 4 +fn default_webhooks_timeout() -> u16 { + WEBHOOKS_TIMEOUT } impl Default for WebHooksConfig { fn default() -> WebHooksConfig { WebHooksConfig { - tx_received_url: None, - header_received_url: None, - block_received_url: None, - block_accepted_url: None, - nthreads: default_nthreads(), - timeout: default_timeout(), + tx_received_url: default_webhooks_tx_received_url(), + header_received_url: default_webhooks_header_received_url(), + block_received_url: default_webhooks_block_received_url(), + block_accepted_url: default_webhooks_block_accepted_url(), + nthreads: default_webhooks_nthreads(), + timeout: default_webhooks_timeout(), } } } diff --git a/servers/src/grin/seed.rs b/servers/src/grin/seed.rs index 7418278ad1..979da45913 100644 --- a/servers/src/grin/seed.rs +++ b/servers/src/grin/seed.rs @@ -156,7 +156,7 @@ fn monitor_peers( p2p::State::Banned => { let interval = Utc::now().timestamp() - x.last_banned; // Unban peer - if interval >= config.ban_window() { + if interval >= config.ban_window { if let Err(e) = peers.unban_peer(x.addr) { error!("failed to unban peer {}: {:?}", x.addr, e); } @@ -188,8 +188,8 @@ fn monitor_peers( // maintenance step first, clean up p2p server peers peers.clean_peers( - config.peer_max_inbound_count() as usize, - config.peer_max_outbound_count() as usize, + config.peer_max_inbound_count as usize, + config.peer_max_outbound_count as usize, ); if peers.enough_outbound_peers() { diff --git a/servers/src/grin/server.rs b/servers/src/grin/server.rs index 3d13a07c64..635f26a299 100644 --- a/servers/src/grin/server.rs +++ b/servers/src/grin/server.rs @@ -105,10 +105,8 @@ impl Server { } } - if let Some(s) = enable_test_miner { - if s { - serv.start_test_miner(test_miner_wallet_url, serv.stop_state.clone()); - } + if enable_test_miner { + serv.start_test_miner(test_miner_wallet_url, serv.stop_state.clone()); } info_callback(serv); @@ -145,13 +143,6 @@ impl Server { // Obtain our lock_file or fail immediately with an error. let lock_file = Server::one_grin_at_a_time(&config)?; - // Defaults to None (optional) in config file. - // This translates to false here. - let archive_mode = match config.archive_mode { - None => false, - Some(b) => b, - }; - let stop_state = Arc::new(StopState::new()); // Shared cache for verification results. @@ -189,7 +180,7 @@ impl Server { genesis.clone(), pow::verify_size, verifier_cache.clone(), - archive_mode, + config.archive_mode, )?); pool_adapter.set_chain(shared_chain.clone()); @@ -246,10 +237,7 @@ impl Server { )?); } - // Defaults to None (optional) in config file. - // This translates to false here so we do not skip by default. - let skip_sync_wait = config.skip_sync_wait.unwrap_or(false); - sync_state.update(SyncStatus::AwaitingPeers(!skip_sync_wait)); + sync_state.update(SyncStatus::AwaitingPeers(!config.skip_sync_wait)); let sync_thread = sync::run_sync( sync_state.clone(), diff --git a/src/bin/cmd/server.rs b/src/bin/cmd/server.rs index 72c7d127fc..916a2d5491 100644 --- a/src/bin/cmd/server.rs +++ b/src/bin/cmd/server.rs @@ -43,7 +43,7 @@ pub fn start_server(config: servers::ServerConfig) { fn start_server_tui(config: servers::ServerConfig) { // Run the UI controller.. here for now for simplicity to access // everything it might need - if config.run_tui.unwrap_or(false) { + if config.run_tui { warn!("Starting GRIN in UI mode..."); servers::Server::start(config, |serv: servers::Server| { let mut controller = ui::Controller::new().unwrap_or_else(|e| { diff --git a/src/bin/grin.rs b/src/bin/grin.rs index 281b4e2e2d..6180592977 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -138,8 +138,7 @@ fn real_main() -> i32 { if let Some(mut config) = node_config.clone() { let mut l = config.members.as_mut().unwrap().logging.clone().unwrap(); - let run_tui = config.members.as_mut().unwrap().server.run_tui; - if let Some(true) = run_tui { + if config.members.as_mut().unwrap().server.run_tui { l.log_to_stdout = false; l.tui_running = Some(true); } @@ -177,7 +176,7 @@ fn real_main() -> i32 { Ok(_) => 0, Err(_) => 1, } - }, + } // If nothing is specified, try to just use the config file instead // this could possibly become the way to configure most things diff --git a/util/src/logger.rs b/util/src/logger.rs index e800c44ffe..5b8288f46f 100644 --- a/util/src/logger.rs +++ b/util/src/logger.rs @@ -18,7 +18,7 @@ use std::ops::Deref; use backtrace::Backtrace; use std::{panic, thread}; -use crate::types::{self, LogLevel, LoggingConfig}; +use crate::types::{LogLevel, LoggingConfig}; use log::{LevelFilter, Record}; use log4rs; @@ -123,11 +123,8 @@ pub fn init_logger(config: Option) { let filter = Box::new(ThresholdFilter::new(level_file)); let file: Box = { if let Some(size) = c.log_max_size { - let count = c - .log_max_files - .unwrap_or_else(|| types::DEFAULT_ROTATE_LOG_FILES); let roller = FixedWindowRoller::builder() - .build(&format!("{}.{{}}.gz", c.log_file_path), count) + .build(&format!("{}.{{}}.gz", c.log_file_path), c.log_max_files) .unwrap(); let trigger = SizeTrigger::new(size); diff --git a/util/src/types.rs b/util/src/types.rs index ed7788e8ef..23072bc9ea 100644 --- a/util/src/types.rs +++ b/util/src/types.rs @@ -14,6 +14,30 @@ //! Logging configuration types +/// whether to log to stdout +const LOGGING_LOG_TO_STDOUT: bool = true; + +/// logging level for stdout +const LOGGING_STDOUT_LOG_LEVEL: LogLevel = LogLevel::Warning; + +/// whether to log to file +const LOGGING_LOG_TO_FILE: bool = true; + +/// log file level +const LOGGING_FILE_LOG_LEVEL: LogLevel = LogLevel::Info; + +/// Log file path +const LOGGING_LOG_FILE_PATH: &str = "grin.log"; + +/// Whether to append to log file or replace +const LOGGING_LOG_FILE_APPEND: bool = true; + +/// Size of the log in bytes to rotate over (optional) +const LOGGING_LOG_MAX_SIZE: u64 = 1024 * 1024 * 16; // 16 megabytes default + +/// 32 log files to rotate over by default +const LOGGING_ROTATE_LOG_FILES: u32 = 32 as u32; + /// Log level types #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum LogLevel { @@ -29,48 +53,90 @@ pub enum LogLevel { Trace, } -/// 32 log files to rotate over by default -pub const DEFAULT_ROTATE_LOG_FILES: u32 = 32 as u32; - /// Logging config #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct LoggingConfig { /// whether to log to stdout + #[serde(default = "default_logging_log_to_stdout")] pub log_to_stdout: bool, /// logging level for stdout + #[serde(default = "default_logging_stdout_log_level")] pub stdout_log_level: LogLevel, /// whether to log to file + #[serde(default = "default_logging_log_to_file")] pub log_to_file: bool, /// log file level + #[serde(default = "default_logging_file_log_level")] pub file_log_level: LogLevel, /// Log file path + #[serde(default = "default_logging_log_file_path")] pub log_file_path: String, /// Whether to append to log or replace + #[serde(default = "default_logging_log_file_append")] pub log_file_append: bool, /// Size of the log in bytes to rotate over (optional) + #[serde(default = "default_logging_log_max_size")] pub log_max_size: Option, /// Number of the log files to rotate over (optional) - pub log_max_files: Option, + #[serde(default = "default_logging_log_max_files")] + pub log_max_files: u32, /// Whether the tui is running (optional) + #[serde(default = "default_logging_tui_running")] pub tui_running: Option, } impl Default for LoggingConfig { fn default() -> LoggingConfig { LoggingConfig { - log_to_stdout: true, - stdout_log_level: LogLevel::Warning, - log_to_file: true, - file_log_level: LogLevel::Info, - log_file_path: String::from("grin.log"), - log_file_append: true, - log_max_size: Some(1024 * 1024 * 16), // 16 megabytes default - log_max_files: Some(DEFAULT_ROTATE_LOG_FILES), - tui_running: None, + log_to_stdout: default_logging_log_to_stdout(), + stdout_log_level: default_logging_stdout_log_level(), + log_to_file: default_logging_log_to_file(), + file_log_level: default_logging_file_log_level(), + log_file_path: default_logging_log_file_path(), + log_file_append: default_logging_log_file_append(), + log_max_size: default_logging_log_max_size(), + log_max_files: default_logging_log_max_files(), + tui_running: default_logging_tui_running(), } } } +fn default_logging_log_to_stdout() -> bool { + LOGGING_LOG_TO_STDOUT +} + +fn default_logging_stdout_log_level() -> LogLevel { + LOGGING_STDOUT_LOG_LEVEL +} + +fn default_logging_log_to_file() -> bool { + LOGGING_LOG_TO_FILE +} + +fn default_logging_file_log_level() -> LogLevel { + LOGGING_FILE_LOG_LEVEL +} + +fn default_logging_log_file_path() -> String { + LOGGING_LOG_FILE_PATH.to_string() +} + +fn default_logging_log_file_append() -> bool { + LOGGING_LOG_FILE_APPEND +} + +fn default_logging_log_max_size() -> Option { + Some(LOGGING_LOG_MAX_SIZE) +} + +fn default_logging_log_max_files() -> u32 { + LOGGING_ROTATE_LOG_FILES +} + +fn default_logging_tui_running() -> Option { + None +} + use std::ops::Deref; use zeroize::Zeroize; /// Zeroing string, mainly useful for password