From bd5577c0a40e9a61b168434bf7dacc2aaed28e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 30 May 2023 13:16:22 +0100 Subject: [PATCH] nym-api config migration --- common/config/src/legacy_helpers.rs | 8 + nym-api/src/support/cli/mod.rs | 56 ++- nym-api/src/support/config/helpers.rs | 41 ++ nym-api/src/support/config/mod.rs | 18 +- .../src/support/config/old_config_v1_1_20.rs | 371 ++++++++++++++++++ nym-api/src/support/config/template.rs | 100 +++-- 6 files changed, 512 insertions(+), 82 deletions(-) create mode 100644 nym-api/src/support/config/helpers.rs create mode 100644 nym-api/src/support/config/old_config_v1_1_20.rs diff --git a/common/config/src/legacy_helpers.rs b/common/config/src/legacy_helpers.rs index e8156d7a0a..191586ee89 100644 --- a/common/config/src/legacy_helpers.rs +++ b/common/config/src/legacy_helpers.rs @@ -19,6 +19,14 @@ pub mod nym_config { fn default_root_directory() -> PathBuf; + fn default_data_directory(id: &str) -> PathBuf { + Self::default_data_directory_with_root(Self::default_root_directory(), id) + } + + fn default_data_directory_with_root>(root: P, id: &str) -> PathBuf { + root.as_ref().join(id).join(DATA_DIR) + } + fn default_config_directory(id: &str) -> PathBuf { Self::default_config_directory_with_root(Self::default_root_directory(), id) } diff --git a/nym-api/src/support/cli/mod.rs b/nym-api/src/support/cli/mod.rs index 1aae135354..facbc6c7ff 100644 --- a/nym-api/src/support/cli/mod.rs +++ b/nym-api/src/support/cli/mod.rs @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use super::config::Config; -use crate::support::config::{ - default_config_directory, default_config_filepath, default_data_directory, -}; +use crate::support::config::default_config_filepath; +use crate::support::config::helpers::{initialise_new, try_load_current_config}; use ::nym_config::defaults::var_names::{MIXNET_CONTRACT_ADDRESS, VESTING_CONTRACT_ADDRESS}; use anyhow::Result; use clap::Parser; @@ -12,7 +11,6 @@ use lazy_static::lazy_static; use nym_bin_common::build_information::BinaryBuildInformation; use nym_config::OptionalSet; use nym_validator_client::nyxd; -use std::fs; lazy_static! { pub static ref PRETTY_BUILD_INFORMATION: String = @@ -109,34 +107,6 @@ pub(crate) struct CliArgs { pub(crate) enable_coconut: Option, } -pub(crate) fn build_config(args: CliArgs) -> Result { - let id = args.id.clone(); - - // try to load config from the file, if it doesn't exist, use default values - let config = match Config::read_from_default_path(&id) { - Ok(cfg) => cfg, - Err(_) => { - let config_path = default_config_filepath(&id); - warn!( - "Could not load the configuration file from {}. Either the file did not exist or was malformed. Using the default values instead", - config_path.display() - ); - - let config = Config::new(&id); - fs::create_dir_all(default_config_directory(&id)) - .expect("Could not create config directory"); - fs::create_dir_all(default_data_directory(&id)) - .expect("Could not create data directory"); - crate::coconut::dkg::controller::init_keypair(&config.coconut_signer)?; - config - } - }; - - let config = override_config(config, args); - - Ok(config) -} - pub(crate) fn override_config(config: Config, args: CliArgs) -> Config { config .with_optional(Config::with_custom_nyxd_validator, args.nyxd_validator) @@ -172,3 +142,25 @@ pub(crate) fn override_config(config: Config, args: CliArgs) -> Config { .with_optional(Config::with_announce_address, args.announce_address) .with_optional(Config::with_coconut_signer_enabled, args.enable_coconut) } + +pub(crate) fn build_config(args: CliArgs) -> Result { + let id = args.id.clone(); + + // try to load config from the file, if it doesn't exist, use default values + let config = match try_load_current_config(&id) { + Ok(cfg) => cfg, + Err(err) => { + let config_path = default_config_filepath(&id); + warn!( + "Could not load the configuration file from {}: {err}. Either the file did not exist or was malformed. Using the default values instead", + config_path.display() + ); + + initialise_new(&id)? + } + }; + + let config = override_config(config, args); + + Ok(config) +} diff --git a/nym-api/src/support/config/helpers.rs b/nym-api/src/support/config/helpers.rs new file mode 100644 index 0000000000..84688a0b62 --- /dev/null +++ b/nym-api/src/support/config/helpers.rs @@ -0,0 +1,41 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::support::config::old_config_v1_1_20::ConfigV1_1_20; +use crate::support::config::{default_config_directory, default_data_directory, Config}; +use anyhow::Result; +use std::{fs, io}; + +fn try_upgrade_v1_1_20_config(id: &str) -> Result<()> { + use nym_config::legacy_helpers::nym_config::MigrationNymConfig; + + // explicitly load it as v1.1.20 (which is incompatible with the current, i.e. 1.1.21+) + let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(()); + }; + info!("It seems the nym-api is using <= v1.1.20 config template."); + info!("It is going to get updated to the current specification."); + + let updated: Config = old_config.into(); + Ok(updated.save_to_default_location()?) +} + +fn init_paths(id: &str) -> io::Result<()> { + fs::create_dir_all(default_data_directory(id))?; + fs::create_dir_all(default_config_directory(id)) +} + +pub(crate) fn initialise_new(id: &str) -> Result { + let config = Config::new(id); + init_paths(id)?; + crate::coconut::dkg::controller::init_keypair(&config.coconut_signer)?; + Ok(config) +} + +pub(crate) fn try_load_current_config(id: &str) -> Result { + try_upgrade_v1_1_20_config(id)?; + + Ok(Config::read_from_default_path(id)?) +} diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index 4afe798451..cd19cf1e4a 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -18,6 +18,8 @@ use std::time::Duration; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; +pub(crate) mod helpers; +pub(crate) mod old_config_v1_1_20; mod persistence; mod template; @@ -228,6 +230,7 @@ pub struct Base { vesting_contract_address: nyxd::AccountId, /// Mnemonic used for rewarding and/or multisig operations + // TODO: similarly to the note in gateway, this should get moved to a separate file mnemonic: bip39::Mnemonic, } @@ -254,10 +257,9 @@ pub struct NetworkMonitor { /// Specifies whether network monitoring service is enabled in this process. pub enabled: bool, - #[serde(flatten)] pub storage_paths: NetworkMonitorPaths, - #[serde(flatten)] + #[serde(default)] pub debug: NetworkMonitorDebug, } @@ -350,10 +352,9 @@ impl Default for NetworkMonitorDebug { #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct NodeStatusAPI { // pub enabled: bool, - #[serde(flatten)] pub storage_paths: NodeStatusAPIPaths, - #[serde(flatten)] + #[serde(default)] pub debug: NodeStatusAPIDebug, } @@ -389,7 +390,7 @@ pub struct TopologyCacher { // pub enabled: bool, // pub paths: TopologyCacherPathfinder, - #[serde(flatten)] + #[serde(default)] pub debug: TopologyCacherDebug, } @@ -414,7 +415,7 @@ pub struct CirculatingSupplyCacher { pub enabled: bool, // pub paths: CirculatingSupplyCacherPathfinder, - #[serde(flatten)] + #[serde(default)] pub debug: CirculatingSupplyCacherDebug, } @@ -450,7 +451,7 @@ pub struct Rewarding { // this should really be a thing too... // pub paths: RewardingPathfinder, - #[serde(flatten)] + #[serde(default)] pub debug: RewardingDebug, } @@ -488,10 +489,9 @@ pub struct CoconutSigner { pub announce_address: Url, - #[serde(flatten)] pub storage_paths: CoconutSignerPaths, - #[serde(flatten)] + #[serde(default)] pub debug: CoconutSignerDebug, } diff --git a/nym-api/src/support/config/old_config_v1_1_20.rs b/nym-api/src/support/config/old_config_v1_1_20.rs new file mode 100644 index 0000000000..373908533b --- /dev/null +++ b/nym-api/src/support/config/old_config_v1_1_20.rs @@ -0,0 +1,371 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::support::config::persistence::{ + CoconutSignerPaths, NetworkMonitorPaths, NodeStatusAPIPaths, +}; +use crate::support::config::{ + Base, CirculatingSupplyCacher, CirculatingSupplyCacherDebug, CoconutSigner, CoconutSignerDebug, + Config, NetworkMonitor, NetworkMonitorDebug, NodeStatusAPI, NodeStatusAPIDebug, Rewarding, + RewardingDebug, TopologyCacher, TopologyCacherDebug, +}; +use nym_config::legacy_helpers::nym_config::MigrationNymConfig; +use nym_validator_client::nyxd; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; +use std::time::Duration; +use url::Url; + +const DEFAULT_NYM_API_PORT: u16 = 8080; +const MIXNET_CONTRACT_ADDRESS: &str = + "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; +const VESTING_CONTRACT_ADDRESS: &str = + "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; + +const DEFAULT_LOCAL_VALIDATOR: &str = "http://localhost:26657"; + +const DEFAULT_DKG_CONTRACT_POLLING_RATE: Duration = Duration::from_secs(10); + +const DEFAULT_GATEWAY_SENDING_RATE: usize = 200; +const DEFAULT_MAX_CONCURRENT_GATEWAY_CLIENTS: usize = 50; +const DEFAULT_PACKET_DELIVERY_TIMEOUT: Duration = Duration::from_secs(20); +const DEFAULT_MONITOR_RUN_INTERVAL: Duration = Duration::from_secs(15 * 60); +const DEFAULT_GATEWAY_PING_INTERVAL: Duration = Duration::from_secs(60); +// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause +// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the +// bandwidth bridging protocol, we can come back to a smaller timeout value +const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60); +// This timeout value should be big enough to accommodate an initial bandwidth acquirement +const DEFAULT_GATEWAY_CONNECTION_TIMEOUT: Duration = Duration::from_secs(2 * 60); + +const DEFAULT_TEST_ROUTES: usize = 3; +const DEFAULT_MINIMUM_TEST_ROUTES: usize = 1; +const DEFAULT_ROUTE_TEST_PACKETS: usize = 1000; +const DEFAULT_PER_NODE_TEST_PACKETS: usize = 3; + +const DEFAULT_TOPOLOGY_CACHE_INTERVAL: Duration = Duration::from_secs(30); +const DEFAULT_NODE_STATUS_CACHE_INTERVAL: Duration = Duration::from_secs(120); +const DEFAULT_CIRCULATING_SUPPLY_CACHE_INTERVAL: Duration = Duration::from_secs(3600); +const DEFAULT_MONITOR_THRESHOLD: u8 = 60; +const DEFAULT_MIN_MIXNODE_RELIABILITY: u8 = 50; +const DEFAULT_MIN_GATEWAY_RELIABILITY: u8 = 20; + +#[derive(Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_20 { + #[serde(default)] + base: BaseV1_1_20, + + #[serde(default)] + network_monitor: NetworkMonitorV1_1_20, + + #[serde(default)] + node_status_api: NodeStatusAPIV1_1_20, + + #[serde(default)] + topology_cacher: TopologyCacherV1_1_20, + + #[serde(default)] + circulating_supply_cacher: CirculatingSupplyCacherV1_1_20, + + #[serde(default)] + rewarding: RewardingV1_1_20, + + #[serde(default)] + coconut_signer: CoconutSignerV1_1_20, +} + +impl From for Config { + fn from(value: ConfigV1_1_20) -> Self { + // this value was never properly saved (probably a bug) + // so explicitly set it to the default + + let dkg_persistent_state_path = + CoconutSignerV1_1_20::default_dkg_persistent_state_path(&value.base.id); + + Config { + base: Base { + id: value.base.id, + local_validator: value.base.local_validator, + mixnet_contract_address: value.base.mixnet_contract_address, + vesting_contract_address: value.base.vesting_contract_address, + mnemonic: value.base.mnemonic, + }, + network_monitor: NetworkMonitor { + enabled: value.network_monitor.enabled, + storage_paths: NetworkMonitorPaths { + credentials_database_path: value.network_monitor.credentials_database_path, + }, + debug: NetworkMonitorDebug { + min_mixnode_reliability: value.network_monitor.min_mixnode_reliability, + min_gateway_reliability: value.network_monitor.min_gateway_reliability, + disabled_credentials_mode: value.network_monitor.disabled_credentials_mode, + run_interval: value.network_monitor.run_interval, + gateway_ping_interval: value.network_monitor.gateway_ping_interval, + gateway_sending_rate: value.network_monitor.gateway_sending_rate, + max_concurrent_gateway_clients: value + .network_monitor + .max_concurrent_gateway_clients, + gateway_response_timeout: value.network_monitor.gateway_response_timeout, + gateway_connection_timeout: value.network_monitor.gateway_connection_timeout, + packet_delivery_timeout: value.network_monitor.packet_delivery_timeout, + test_routes: value.network_monitor.test_routes, + minimum_test_routes: value.network_monitor.minimum_test_routes, + route_test_packets: value.network_monitor.route_test_packets, + per_node_test_packets: value.network_monitor.per_node_test_packets, + }, + }, + node_status_api: NodeStatusAPI { + storage_paths: NodeStatusAPIPaths { + database_path: value.node_status_api.database_path, + }, + debug: NodeStatusAPIDebug { + caching_interval: value.node_status_api.caching_interval, + }, + }, + topology_cacher: TopologyCacher { + debug: TopologyCacherDebug { + caching_interval: value.topology_cacher.caching_interval, + }, + }, + circulating_supply_cacher: CirculatingSupplyCacher { + enabled: value.circulating_supply_cacher.enabled, + debug: CirculatingSupplyCacherDebug { + caching_interval: value.circulating_supply_cacher.caching_interval, + }, + }, + rewarding: Rewarding { + enabled: value.rewarding.enabled, + debug: RewardingDebug { + minimum_interval_monitor_threshold: value + .rewarding + .minimum_interval_monitor_threshold, + }, + }, + coconut_signer: CoconutSigner { + enabled: value.coconut_signer.enabled, + announce_address: value.base.announce_address, + storage_paths: CoconutSignerPaths { + dkg_persistent_state_path, + verification_key_path: value.coconut_signer.verification_key_path, + secret_key_path: value.coconut_signer.secret_key_path, + decryption_key_path: value.coconut_signer.decryption_key_path, + public_key_with_proof_path: value.coconut_signer.public_key_with_proof_path, + }, + debug: CoconutSignerDebug { + dkg_contract_polling_rate: value.coconut_signer.dkg_contract_polling_rate, + }, + }, + } + } +} + +impl MigrationNymConfig for ConfigV1_1_20 { + fn default_root_directory() -> PathBuf { + dirs::home_dir() + .expect("Failed to evaluate $HOME value") + .join(".nym") + .join("nym-api") + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct BaseV1_1_20 { + /// ID specifies the human readable ID of this particular nym-api. + id: String, + + local_validator: Url, + + /// Address announced to the directory server for the clients to connect to. + // It is useful, say, in NAT scenarios or wanting to more easily update actual IP address + // later on by using name resolvable with a DNS query, such as `nymtech.net`. + announce_address: Url, + + /// Address of the validator contract managing the network + mixnet_contract_address: nyxd::AccountId, + + /// Address of the vesting contract holding locked tokens + vesting_contract_address: nyxd::AccountId, + + /// Mnemonic used for rewarding and/or multisig operations + mnemonic: bip39::Mnemonic, +} + +impl Default for BaseV1_1_20 { + fn default() -> Self { + let default_validator: Url = DEFAULT_LOCAL_VALIDATOR + .parse() + .expect("default local validator is malformed!"); + let mut default_announce_address = default_validator.clone(); + default_announce_address + .set_port(Some(DEFAULT_NYM_API_PORT)) + .expect("default local validator is malformed!"); + + BaseV1_1_20 { + id: String::default(), + local_validator: default_validator, + announce_address: default_announce_address, + mixnet_contract_address: MIXNET_CONTRACT_ADDRESS.parse().unwrap(), + vesting_contract_address: VESTING_CONTRACT_ADDRESS.parse().unwrap(), + mnemonic: bip39::Mnemonic::generate(24).unwrap(), + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct NetworkMonitorV1_1_20 { + min_mixnode_reliability: u8, // defaults to 50 + min_gateway_reliability: u8, // defaults to 20 + enabled: bool, + #[serde(default)] + disabled_credentials_mode: bool, + #[serde(with = "humantime_serde")] + run_interval: Duration, + #[serde(with = "humantime_serde")] + gateway_ping_interval: Duration, + gateway_sending_rate: usize, + max_concurrent_gateway_clients: usize, + #[serde(with = "humantime_serde")] + gateway_response_timeout: Duration, + #[serde(with = "humantime_serde")] + gateway_connection_timeout: Duration, + #[serde(with = "humantime_serde")] + packet_delivery_timeout: Duration, + credentials_database_path: PathBuf, + test_routes: usize, + minimum_test_routes: usize, + route_test_packets: usize, + per_node_test_packets: usize, +} + +impl Default for NetworkMonitorV1_1_20 { + fn default() -> Self { + NetworkMonitorV1_1_20 { + min_mixnode_reliability: DEFAULT_MIN_MIXNODE_RELIABILITY, + min_gateway_reliability: DEFAULT_MIN_GATEWAY_RELIABILITY, + enabled: false, + disabled_credentials_mode: true, + run_interval: DEFAULT_MONITOR_RUN_INTERVAL, + gateway_ping_interval: DEFAULT_GATEWAY_PING_INTERVAL, + gateway_sending_rate: DEFAULT_GATEWAY_SENDING_RATE, + max_concurrent_gateway_clients: DEFAULT_MAX_CONCURRENT_GATEWAY_CLIENTS, + gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, + gateway_connection_timeout: DEFAULT_GATEWAY_CONNECTION_TIMEOUT, + packet_delivery_timeout: DEFAULT_PACKET_DELIVERY_TIMEOUT, + credentials_database_path: Default::default(), + test_routes: DEFAULT_TEST_ROUTES, + minimum_test_routes: DEFAULT_MINIMUM_TEST_ROUTES, + route_test_packets: DEFAULT_ROUTE_TEST_PACKETS, + per_node_test_packets: DEFAULT_PER_NODE_TEST_PACKETS, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct NodeStatusAPIV1_1_20 { + database_path: PathBuf, + #[serde(with = "humantime_serde")] + caching_interval: Duration, +} + +impl Default for NodeStatusAPIV1_1_20 { + fn default() -> Self { + NodeStatusAPIV1_1_20 { + database_path: Default::default(), + caching_interval: DEFAULT_NODE_STATUS_CACHE_INTERVAL, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct TopologyCacherV1_1_20 { + #[serde(with = "humantime_serde")] + caching_interval: Duration, +} + +impl Default for TopologyCacherV1_1_20 { + fn default() -> Self { + TopologyCacherV1_1_20 { + caching_interval: DEFAULT_TOPOLOGY_CACHE_INTERVAL, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct CirculatingSupplyCacherV1_1_20 { + enabled: bool, + + #[serde(with = "humantime_serde")] + caching_interval: Duration, +} + +impl Default for CirculatingSupplyCacherV1_1_20 { + fn default() -> Self { + CirculatingSupplyCacherV1_1_20 { + enabled: true, + caching_interval: DEFAULT_CIRCULATING_SUPPLY_CACHE_INTERVAL, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct RewardingV1_1_20 { + enabled: bool, + minimum_interval_monitor_threshold: u8, +} + +impl Default for RewardingV1_1_20 { + fn default() -> Self { + RewardingV1_1_20 { + enabled: false, + minimum_interval_monitor_threshold: DEFAULT_MONITOR_THRESHOLD, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct CoconutSignerV1_1_20 { + enabled: bool, + dkg_persistent_state_path: PathBuf, + verification_key_path: PathBuf, + secret_key_path: PathBuf, + decryption_key_path: PathBuf, + public_key_with_proof_path: PathBuf, + dkg_contract_polling_rate: Duration, +} + +impl CoconutSignerV1_1_20 { + pub const DKG_PERSISTENT_STATE_FILE: &'static str = "dkg_persistent_state.json"; + + fn default_dkg_persistent_state_path(id: &str) -> PathBuf { + ConfigV1_1_20::default_data_directory(id).join(Self::DKG_PERSISTENT_STATE_FILE) + } +} + +impl Default for CoconutSignerV1_1_20 { + fn default() -> Self { + Self { + enabled: Default::default(), + dkg_persistent_state_path: Default::default(), + verification_key_path: Default::default(), + secret_key_path: Default::default(), + decryption_key_path: Default::default(), + public_key_with_proof_path: Default::default(), + dkg_contract_polling_rate: DEFAULT_DKG_CONTRACT_POLLING_RATE, + } + } +} diff --git a/nym-api/src/support/config/template.rs b/nym-api/src/support/config/template.rs index 2ed373fd91..7ef105d91d 100644 --- a/nym-api/src/support/config/template.rs +++ b/nym-api/src/support/config/template.rs @@ -15,11 +15,6 @@ id = '{{ base.id }}' # Validator server to which the API will be getting information about the network. local_validator = '{{ base.local_validator }}' -# Address announced to the directory server for the clients to connect to. -# It is useful, say, in NAT scenarios or wanting to more easily update actual IP address -# later on by using name resolvable with a DNS query, such as `nymtech.net`. -announce_address = '{{ base.announce_address }}' - # Address of the validator contract managing the network. mixnet_contract_address = '{{ base.mixnet_contract_address }}' @@ -29,59 +24,72 @@ vesting_contract_address = '{{ base.vesting_contract_address }}' # Mnemonic used for rewarding and validator interaction mnemonic = '{{ base.mnemonic }}' + ##### network monitor config options ##### [network_monitor] # Specifies whether network monitoring service is enabled in this process. enabled = {{ network_monitor.enabled }} +[network_monitor.storage_paths] + +# Path to the database containing bandwidth credentials of this client. +credentials_database_path = '{{ network_monitor.storage_paths.credentials_database_path }}' + +[network_monitor.debug] + # Indicates whether this validator api is running in a disabled credentials mode, thus attempting # to claim bandwidth without presenting bandwidth credentials. -disabled_credentials_mode = {{ network_monitor.disabled_credentials_mode }} +disabled_credentials_mode = {{ network_monitor.debug.disabled_credentials_mode }} # Specifies the interval at which the network monitor sends the test packets. -run_interval = '{{ network_monitor.run_interval }}' - -# Specifies interval at which we should be sending ping packets to all active gateways -# in order to keep the websocket connections alive. -gateway_ping_interval = '{{ network_monitor.gateway_ping_interval }}' - -# Specifies maximum rate (in packets per second) of test packets being sent to gateway -gateway_sending_rate = {{ network_monitor.gateway_sending_rate }} - -# Maximum number of gateway clients the network monitor will try to talk to concurrently. -max_concurrent_gateway_clients = {{ network_monitor.max_concurrent_gateway_clients }} - -# Maximum allowed time for receiving gateway response. -gateway_response_timeout = '{{ network_monitor.gateway_response_timeout }}' - -# Maximum allowed time for the gateway connection to get established. -gateway_connection_timeout = '{{ network_monitor.gateway_connection_timeout }}' - -# Specifies the duration the monitor is going to wait after sending all measurement -# packets before declaring nodes unreachable. -packet_delivery_timeout = '{{ network_monitor.packet_delivery_timeout }}' - -credentials_database_path = '{{ network_monitor.credentials_database_path }}' +run_interval = '{{ network_monitor.debug.run_interval }}' # Desired number of test routes to be constructed (and working) during a monitor test run. -test_routes = {{ network_monitor.test_routes }} +test_routes = {{ network_monitor.debug.test_routes }} # The minimum number of test routes that need to be constructed (and working) in order for # a monitor test run to be valid. -minimum_test_routes = {{ network_monitor.minimum_test_routes }} +minimum_test_routes = {{ network_monitor.debug.minimum_test_routes }} # Number of test packets sent via each pseudorandom route to verify whether they work correctly, # before using them for testing the rest of the network. -route_test_packets = {{ network_monitor.route_test_packets }} +route_test_packets = {{ network_monitor.debug.route_test_packets }} # Number of test packets sent to each node during regular monitor test run. -per_node_test_packets = {{ network_monitor.per_node_test_packets }} +per_node_test_packets = {{ network_monitor.debug.per_node_test_packets }} -[node_status_api] + +##### node status api config options ##### + +[node_status_api.storage_paths] # Path to the database file containing uptime statuses for all mixnodes and gateways. -database_path = '{{ node_status_api.database_path }}' +database_path = '{{ node_status_api.storage_paths.database_path }}' + +[node_status_api.debug] + +caching_interval = '{{ node_status_api.debug.caching_interval }}' + + +##### topology cacher config options ##### + +[topology_cacher.debug] + +caching_interval = '{{ topology_cacher.debug.caching_interval }}' + + +##### circulating supply cacher config options ##### + +[circulating_supply_cacher] + +# Specifies whether circulating supply caching service is enabled in this process. +enabled = {{ circulating_supply_cacher.enabled }} + +[circulating_supply_cacher.debug] + +caching_interval = '{{ circulating_supply_cacher.debug.caching_interval }}' + ##### rewarding config options ##### @@ -90,26 +98,36 @@ database_path = '{{ node_status_api.database_path }}' # Specifies whether rewarding service is enabled in this process. enabled = {{ rewarding.enabled }} +[rewarding.debug] + # Specifies the minimum percentage of monitor test run data present in order to # distribute rewards for given interval. # Note, only values in range 0-100 are valid -minimum_interval_monitor_threshold = {{ rewarding.minimum_interval_monitor_threshold }} +minimum_interval_monitor_threshold = {{ rewarding.debug.minimum_interval_monitor_threshold }} [coconut_signer] # Specifies whether coconut signing protocol is enabled in this process. enabled = {{ coconut_signer.enabled }} -# Path to the coconut verification key -verification_key_path = '{{ coconut_signer.verification_key_path }}' +# address of this nym-api as announced to other instances for the purposes of performing the DKG. +announce_address = '{{ coconut_signer.announce_address }}' + +[coconut_signer.storage_paths] + +# Path to a JSON file where state is persisted between different stages of DKG. +dkg_persistent_state_path = '{{ coconut_signer.storage_paths.dkg_persistent_state_path }}' # Path to the coconut verification key -secret_key_path = '{{ coconut_signer.secret_key_path }}' +verification_key_path = '{{ coconut_signer.storage_paths.verification_key_path }}' + +# Path to the coconut verification key +secret_key_path = '{{ coconut_signer.storage_paths.secret_key_path }}' # Path to the dkg dealer decryption key -decryption_key_path = '{{ coconut_signer.decryption_key_path }}' +decryption_key_path = '{{ coconut_signer.storage_paths.decryption_key_path }}' # Path to the dkg dealer public key with proof -public_key_with_proof_path = '{{ coconut_signer.public_key_with_proof_path }}' +public_key_with_proof_path = '{{ coconut_signer.storage_paths.public_key_with_proof_path }}' "#;