mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
334 lines
9.7 KiB
Rust
334 lines
9.7 KiB
Rust
// Copyright 2021 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.
|
|
|
|
//! Public types for config modules
|
|
|
|
use crate::core::global::ChainTypes;
|
|
use crate::util::logger::LoggingConfig;
|
|
use std::fmt;
|
|
use std::io;
|
|
use std::path::PathBuf;
|
|
use std::time::Duration;
|
|
|
|
/// Command-line wallet configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct WalletConfig {
|
|
/// Chain parameters (default to Mainnet if none at the moment)
|
|
pub chain_type: Option<ChainTypes>,
|
|
/// The port this wallet will run on
|
|
pub api_listen_port: u16,
|
|
/// The port this wallet's owner API will run on
|
|
pub owner_api_listen_port: Option<u16>,
|
|
/// Location of the secret for basic auth on the Owner API
|
|
pub api_secret_path: Option<String>,
|
|
/// Location of the node api secret for basic auth on the Grin API
|
|
pub node_api_secret_path: Option<String>,
|
|
/// The api address of a running server node against which transaction inputs
|
|
/// will be checked during send
|
|
pub check_node_api_http_addr: String,
|
|
/// Request timeout for requests to node API.
|
|
pub node_api_request_timeout_secs: Option<u64>,
|
|
/// Whether to include foreign API endpoints on the Owner API
|
|
pub owner_api_include_foreign: Option<bool>,
|
|
/// The directory in which wallet files are stored
|
|
pub data_file_dir: String,
|
|
/// If Some(true), don't cache commits alongside output data
|
|
/// speed improvement, but your commits are in the database
|
|
pub no_commit_cache: Option<bool>,
|
|
/// TLS certificate file
|
|
pub tls_certificate_file: Option<String>,
|
|
/// TLS certificate private key file
|
|
pub tls_certificate_key: Option<String>,
|
|
/// Whether to use the black background color scheme for command line
|
|
/// if enabled, wallet command output color will be suitable for black background terminal
|
|
pub dark_background_color_scheme: Option<bool>,
|
|
/// Scaling factor from transaction weight to transaction fee
|
|
/// should match accept_fee_base parameter in grin-server
|
|
pub accept_fee_base: Option<u64>,
|
|
}
|
|
|
|
impl Default for WalletConfig {
|
|
fn default() -> WalletConfig {
|
|
WalletConfig {
|
|
chain_type: Some(ChainTypes::Mainnet),
|
|
api_listen_port: 3415,
|
|
owner_api_listen_port: Some(WalletConfig::default_owner_api_listen_port()),
|
|
api_secret_path: Some(".owner_api_secret".to_string()),
|
|
node_api_secret_path: Some(".foreign_api_secret".to_string()),
|
|
check_node_api_http_addr: "http://127.0.0.1:3413".to_string(),
|
|
node_api_request_timeout_secs: Some(Self::NODE_API_REQUEST_TIMEOUT_SECS),
|
|
owner_api_include_foreign: Some(false),
|
|
data_file_dir: ".".to_string(),
|
|
no_commit_cache: Some(false),
|
|
tls_certificate_file: None,
|
|
tls_certificate_key: None,
|
|
dark_background_color_scheme: Some(true),
|
|
accept_fee_base: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl WalletConfig {
|
|
/// Default Node API request timeout in seconds.
|
|
pub const NODE_API_REQUEST_TIMEOUT_SECS: u64 = 60;
|
|
|
|
/// API Listen address
|
|
pub fn api_listen_addr(&self) -> String {
|
|
format!("127.0.0.1:{}", self.api_listen_port)
|
|
}
|
|
|
|
/// Default listener port
|
|
pub fn default_owner_api_listen_port() -> u16 {
|
|
3420
|
|
}
|
|
|
|
/// Default listener port
|
|
pub fn default_accept_fee_base() -> u64 {
|
|
500_000
|
|
}
|
|
|
|
/// Use value from config file, defaulting to sensible value if missing.
|
|
pub fn owner_api_listen_port(&self) -> u16 {
|
|
self.owner_api_listen_port
|
|
.unwrap_or_else(WalletConfig::default_owner_api_listen_port)
|
|
}
|
|
|
|
/// Owner API listen address
|
|
pub fn owner_api_listen_addr(&self) -> String {
|
|
format!("127.0.0.1:{}", self.owner_api_listen_port())
|
|
}
|
|
|
|
/// Accept fee base
|
|
pub fn accept_fee_base(&self) -> u64 {
|
|
self.accept_fee_base
|
|
.unwrap_or_else(|| WalletConfig::default_accept_fee_base())
|
|
}
|
|
|
|
/// Node API requests timeout.
|
|
pub fn api_request_timeout(&self) -> Duration {
|
|
Duration::from_secs(
|
|
self.node_api_request_timeout_secs
|
|
.filter(|s| *s > 0)
|
|
.unwrap_or(Self::NODE_API_REQUEST_TIMEOUT_SECS),
|
|
)
|
|
}
|
|
}
|
|
/// Error type wrapping config errors.
|
|
#[derive(Debug)]
|
|
pub enum ConfigError {
|
|
/// Error with parsing of config file
|
|
ParseError(String, String),
|
|
|
|
/// Error with fileIO while reading config file
|
|
FileIOError(String, String),
|
|
|
|
/// No file found
|
|
FileNotFoundError(String),
|
|
|
|
/// Error serializing config values
|
|
SerializationError(String),
|
|
|
|
/// Path doesn't exist
|
|
PathNotFoundError(String),
|
|
}
|
|
|
|
impl fmt::Display for ConfigError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
ConfigError::ParseError(ref file_name, ref message) => write!(
|
|
f,
|
|
"Error parsing configuration file at {} - {}",
|
|
file_name, message
|
|
),
|
|
ConfigError::FileIOError(ref file_name, ref message) => {
|
|
write!(f, "{} {}", message, file_name)
|
|
}
|
|
ConfigError::FileNotFoundError(ref file_name) => {
|
|
write!(f, "Configuration file not found: {}", file_name)
|
|
}
|
|
ConfigError::SerializationError(ref message) => {
|
|
write!(f, "Error serializing configuration: {}", message)
|
|
}
|
|
ConfigError::PathNotFoundError(ref message) => write!(f, "Path not found: {}", message),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<io::Error> for ConfigError {
|
|
fn from(error: io::Error) -> ConfigError {
|
|
ConfigError::FileIOError(
|
|
String::from(""),
|
|
format!("Error loading config file: {}", error),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Tor configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct TorConfig {
|
|
/// whether to use integrated Tor library
|
|
pub use_integrated: Option<bool>,
|
|
/// whether to skip any attempts to send via Tor
|
|
pub skip_send_attempt: Option<bool>,
|
|
/// Whether to start Tor listener on listener startup (default true)
|
|
pub use_tor_listener: bool,
|
|
/// Just the address of the socks proxy for now
|
|
pub socks_proxy_addr: String,
|
|
/// Send configuration directory
|
|
pub send_config_dir: String,
|
|
/// Total timeout for request in seconds.
|
|
pub request_timeout_secs: Option<u64>,
|
|
/// Timeout for bootstrap in seconds.
|
|
pub bootstrap_timeout_secs: Option<u64>,
|
|
/// Tor bridge config
|
|
#[serde(default)]
|
|
pub bridge: TorBridgeConfig,
|
|
/// Tor proxy config
|
|
#[serde(default)]
|
|
pub proxy: TorProxyConfig,
|
|
}
|
|
|
|
impl Default for TorConfig {
|
|
fn default() -> TorConfig {
|
|
TorConfig {
|
|
use_integrated: Some(true),
|
|
skip_send_attempt: Some(false),
|
|
use_tor_listener: true,
|
|
socks_proxy_addr: "127.0.0.1:59050".to_owned(),
|
|
send_config_dir: ".".into(),
|
|
request_timeout_secs: Some(Self::REQUEST_TIMEOUT_SECS),
|
|
bootstrap_timeout_secs: Some(Self::BOOTSTRAP_TIMEOUT_SECS),
|
|
bridge: TorBridgeConfig::default(),
|
|
proxy: TorProxyConfig::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TorConfig {
|
|
/// Tor request timeout in seconds.
|
|
const REQUEST_TIMEOUT_SECS: u64 = 60;
|
|
/// Tor bootstrap timeout in seconds.
|
|
const BOOTSTRAP_TIMEOUT_SECS: u64 = 60;
|
|
|
|
/// Check if attempt to send over Tor is needed using provided possible argument at priority.
|
|
pub fn send_tor(&self, skip_arg: Option<bool>) -> bool {
|
|
if let Some(skip_tor) = skip_arg {
|
|
return !skip_tor;
|
|
}
|
|
!self.skip_send_attempt.unwrap_or(false)
|
|
}
|
|
|
|
/// Request timeout.
|
|
pub fn request_timeout(&self) -> Duration {
|
|
Duration::from_secs(
|
|
self.request_timeout_secs
|
|
.filter(|s| *s > 0)
|
|
.unwrap_or(Self::REQUEST_TIMEOUT_SECS),
|
|
)
|
|
}
|
|
|
|
/// Bootstrap timeout.
|
|
pub fn bootstrap_timeout(&self) -> Duration {
|
|
Duration::from_secs(
|
|
self.bootstrap_timeout_secs
|
|
.filter(|s| *s > 0)
|
|
.unwrap_or(Self::BOOTSTRAP_TIMEOUT_SECS),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Tor Bridge Config
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct TorBridgeConfig {
|
|
/// Path to bridge binary to use with integrated Tor library
|
|
pub bridge_bin_path: Option<String>,
|
|
/// Bridge Line
|
|
pub bridge_line: Option<String>,
|
|
/// Client Option
|
|
pub client_option: Option<String>,
|
|
}
|
|
|
|
impl Default for TorBridgeConfig {
|
|
fn default() -> TorBridgeConfig {
|
|
TorBridgeConfig {
|
|
bridge_bin_path: None,
|
|
bridge_line: None,
|
|
client_option: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for TorBridgeConfig {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "{:?}", self)
|
|
}
|
|
}
|
|
|
|
/// Tor Proxy configuration (useful for protocols such as shadowsocks)
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct TorProxyConfig {
|
|
/// socks4 |socks5 | http(s)
|
|
pub transport: Option<String>,
|
|
/// ip or dns
|
|
pub address: Option<String>,
|
|
/// user for auth - socks5|https(s)
|
|
pub username: Option<String>,
|
|
/// pass for auth - socks5|https(s)
|
|
pub password: Option<String>,
|
|
/// allowed port - proxy
|
|
pub allowed_port: Option<Vec<u16>>,
|
|
}
|
|
|
|
impl Default for TorProxyConfig {
|
|
fn default() -> TorProxyConfig {
|
|
TorProxyConfig {
|
|
transport: None,
|
|
address: None,
|
|
username: None,
|
|
password: None,
|
|
allowed_port: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for TorProxyConfig {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "{:?}", self)
|
|
}
|
|
}
|
|
|
|
/// Wallet should be split into a separate configuration file
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
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 {
|
|
/// Config file version (None == version 1)
|
|
#[serde(default)]
|
|
pub config_file_version: Option<u32>,
|
|
/// Wallet configuration
|
|
#[serde(default)]
|
|
pub wallet: WalletConfig,
|
|
/// Tor config
|
|
pub tor: Option<TorConfig>,
|
|
/// Logging config
|
|
pub logging: Option<LoggingConfig>,
|
|
}
|