mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-24 23:19:34 -05:00
feat(asb): allow config overrides from env vars
- upgrades config crate to 0.13.2 #1087 - adds environment source for config overrides
This commit is contained in:
parent
e279b20629
commit
98296d8fa6
90
Cargo.lock
generated
90
Cargo.lock
generated
@ -93,12 +93,6 @@ version = "0.3.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@ -643,12 +637,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "config"
|
name = "config"
|
||||||
version = "0.11.0"
|
version = "0.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
|
checksum = "11f1667b8320afa80d69d8bbe40830df2c8a06003d86f73d8e003b2c48df416d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"nom 5.1.2",
|
"nom",
|
||||||
|
"pathdiff",
|
||||||
"serde",
|
"serde",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
@ -938,6 +934,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dashmap"
|
||||||
|
version = "5.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"num_cpus",
|
||||||
|
"parking_lot 0.12.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.3.2"
|
version = "2.3.2"
|
||||||
@ -1805,19 +1812,6 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lexical-core"
|
|
||||||
version = "0.7.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec 0.5.2",
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"ryu",
|
|
||||||
"static_assertions",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.137"
|
version = "0.2.137"
|
||||||
@ -2418,17 +2412,6 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "5.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
|
||||||
dependencies = [
|
|
||||||
"lexical-core",
|
|
||||||
"memchr",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.0.0"
|
version = "7.0.0"
|
||||||
@ -2531,9 +2514,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
@ -2643,6 +2626,12 @@ version = "1.0.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem"
|
name = "pem"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -3260,7 +3249,7 @@ version = "1.27.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33c321ee4e17d2b7abe12b5d20c1231db708dd36185c8a21e9de5fed6da4dbe9"
|
checksum = "33c321ee4e17d2b7abe12b5d20c1231db708dd36185c8a21e9de5fed6da4dbe9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.7.2",
|
"arrayvec",
|
||||||
"borsh",
|
"borsh",
|
||||||
"bytecheck",
|
"bytecheck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -3585,6 +3574,32 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serial_test"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92761393ee4dc3ff8f4af487bd58f4307c9329bbedea02cac0089ad9c411e153"
|
||||||
|
dependencies = [
|
||||||
|
"dashmap",
|
||||||
|
"futures",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"parking_lot 0.12.0",
|
||||||
|
"serial_test_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serial_test_derive"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha-1"
|
name = "sha-1"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@ -3806,7 +3821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
|
checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"nom 7.0.0",
|
"nom",
|
||||||
"unicode_categories",
|
"unicode_categories",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4038,6 +4053,7 @@ dependencies = [
|
|||||||
"serde_cbor",
|
"serde_cbor",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
"serial_test",
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
"sigma_fun",
|
"sigma_fun",
|
||||||
"spectral",
|
"spectral",
|
||||||
|
@ -20,7 +20,7 @@ big-bytes = "1"
|
|||||||
bitcoin = { version = "0.29", features = [ "rand", "serde" ] }
|
bitcoin = { version = "0.29", features = [ "rand", "serde" ] }
|
||||||
bmrng = "0.5"
|
bmrng = "0.5"
|
||||||
comfy-table = "6.1"
|
comfy-table = "6.1"
|
||||||
config = { version = "0.11", default-features = false, features = [ "toml" ] }
|
config = { version = "0.13", default-features = false, features = [ "toml" ] }
|
||||||
conquer-once = "0.3"
|
conquer-once = "0.3"
|
||||||
curve25519-dalek = { package = "curve25519-dalek-ng", version = "4" }
|
curve25519-dalek = { package = "curve25519-dalek-ng", version = "4" }
|
||||||
data-encoding = "2.3"
|
data-encoding = "2.3"
|
||||||
@ -81,10 +81,11 @@ monero-harness = { path = "../monero-harness" }
|
|||||||
port_check = "0.1"
|
port_check = "0.1"
|
||||||
proptest = "1"
|
proptest = "1"
|
||||||
serde_cbor = "0.11"
|
serde_cbor = "0.11"
|
||||||
|
serial_test = "0.9"
|
||||||
spectral = "0.6"
|
spectral = "0.6"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
testcontainers = "0.12"
|
testcontainers = "0.12"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
vergen = { version = "7", default-features = false, features = [ "git", "build" ] }
|
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
vergen = { version = "7", default-features = false, features = [ "git", "build" ] }
|
||||||
|
@ -102,12 +102,27 @@ impl Config {
|
|||||||
{
|
{
|
||||||
let config_file = Path::new(&config_file);
|
let config_file = Path::new(&config_file);
|
||||||
|
|
||||||
let mut config = config::Config::new();
|
let config = config::Config::builder()
|
||||||
config.merge(config::File::from(config_file))?;
|
.add_source(config::File::from(config_file))
|
||||||
|
.add_source(
|
||||||
|
config::Environment::with_prefix("ASB")
|
||||||
|
.separator("__")
|
||||||
|
.list_separator(","),
|
||||||
|
)
|
||||||
|
.build()?;
|
||||||
|
|
||||||
config.try_into()
|
config.try_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<config::Config> for Config {
|
||||||
|
type Error = config::ConfigError;
|
||||||
|
|
||||||
|
fn try_from(value: config::Config) -> Result<Self, Self::Error> {
|
||||||
|
value.try_deserialize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
@ -117,13 +132,55 @@ pub struct Data {
|
|||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
|
#[serde(deserialize_with = "addr_list::deserialize")]
|
||||||
pub listen: Vec<Multiaddr>,
|
pub listen: Vec<Multiaddr>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub rendezvous_point: Option<Multiaddr>,
|
pub rendezvous_point: Option<Multiaddr>,
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "addr_list::deserialize")]
|
||||||
pub external_addresses: Vec<Multiaddr>,
|
pub external_addresses: Vec<Multiaddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod addr_list {
|
||||||
|
use libp2p::Multiaddr;
|
||||||
|
use serde::de::Unexpected;
|
||||||
|
use serde::{de, Deserialize, Deserializer};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Multiaddr>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = Value::deserialize(deserializer)?;
|
||||||
|
return match s {
|
||||||
|
Value::String(s) => {
|
||||||
|
let list: Result<Vec<_>, _> = s
|
||||||
|
.split(',')
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(|s| s.parse().map_err(de::Error::custom))
|
||||||
|
.collect();
|
||||||
|
Ok(list?)
|
||||||
|
}
|
||||||
|
Value::Array(a) => {
|
||||||
|
let list: Result<Vec<_>, _> = a
|
||||||
|
.iter()
|
||||||
|
.map(|v| {
|
||||||
|
if let Value::String(s) = v {
|
||||||
|
s.parse().map_err(de::Error::custom)
|
||||||
|
} else {
|
||||||
|
Err(de::Error::custom("expected a string"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(list?)
|
||||||
|
}
|
||||||
|
value => Err(de::Error::invalid_type(
|
||||||
|
Unexpected::Other(&value.to_string()),
|
||||||
|
&"a string or array",
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Bitcoin {
|
pub struct Bitcoin {
|
||||||
@ -172,7 +229,7 @@ impl Default for TorConf {
|
|||||||
|
|
||||||
#[derive(thiserror::Error, Debug, Clone, Copy)]
|
#[derive(thiserror::Error, Debug, Clone, Copy)]
|
||||||
#[error("config not initialized")]
|
#[error("config not initialized")]
|
||||||
pub struct ConfigNotInitialized {}
|
pub struct ConfigNotInitialized;
|
||||||
|
|
||||||
pub fn read_config(config_path: PathBuf) -> Result<Result<Config, ConfigNotInitialized>> {
|
pub fn read_config(config_path: PathBuf) -> Result<Result<Config, ConfigNotInitialized>> {
|
||||||
if config_path.exists() {
|
if config_path.exists() {
|
||||||
@ -334,9 +391,12 @@ pub fn query_user_for_initial_config(testnet: bool) -> Result<Config> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use serial_test::serial;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
// these tests are run serially since env vars affect the whole process
|
||||||
#[test]
|
#[test]
|
||||||
|
#[serial]
|
||||||
fn config_roundtrip_testnet() {
|
fn config_roundtrip_testnet() {
|
||||||
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
||||||
let config_path = Path::join(&temp_dir, "config.toml");
|
let config_path = Path::join(&temp_dir, "config.toml");
|
||||||
@ -358,7 +418,6 @@ mod tests {
|
|||||||
rendezvous_point: None,
|
rendezvous_point: None,
|
||||||
external_addresses: vec![],
|
external_addresses: vec![],
|
||||||
},
|
},
|
||||||
|
|
||||||
monero: Monero {
|
monero: Monero {
|
||||||
wallet_rpc_url: defaults.monero_wallet_rpc_url,
|
wallet_rpc_url: defaults.monero_wallet_rpc_url,
|
||||||
finality_confirmations: None,
|
finality_confirmations: None,
|
||||||
@ -380,6 +439,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[serial]
|
||||||
fn config_roundtrip_mainnet() {
|
fn config_roundtrip_mainnet() {
|
||||||
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
||||||
let config_path = Path::join(&temp_dir, "config.toml");
|
let config_path = Path::join(&temp_dir, "config.toml");
|
||||||
@ -401,7 +461,6 @@ mod tests {
|
|||||||
rendezvous_point: None,
|
rendezvous_point: None,
|
||||||
external_addresses: vec![],
|
external_addresses: vec![],
|
||||||
},
|
},
|
||||||
|
|
||||||
monero: Monero {
|
monero: Monero {
|
||||||
wallet_rpc_url: defaults.monero_wallet_rpc_url,
|
wallet_rpc_url: defaults.monero_wallet_rpc_url,
|
||||||
finality_confirmations: None,
|
finality_confirmations: None,
|
||||||
@ -421,4 +480,60 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[serial]
|
||||||
|
fn env_override() {
|
||||||
|
let temp_dir = tempfile::tempdir().unwrap().path().to_path_buf();
|
||||||
|
let config_path = Path::join(&temp_dir, "config.toml");
|
||||||
|
|
||||||
|
let defaults = Mainnet::getConfigFileDefaults().unwrap();
|
||||||
|
|
||||||
|
let dir = PathBuf::from("/tmp/dir");
|
||||||
|
std::env::set_var("ASB__DATA__DIR", dir.clone());
|
||||||
|
let addr1 = "/dns4/example.com/tcp/9939";
|
||||||
|
let addr2 = "/ip4/1.2.3.4/tcp/9940";
|
||||||
|
let external_addresses = vec![addr1.parse().unwrap(), addr2.parse().unwrap()];
|
||||||
|
let listen = external_addresses.clone();
|
||||||
|
std::env::set_var(
|
||||||
|
"ASB__NETWORK__EXTERNAL_ADDRESSES",
|
||||||
|
format!("{},{}", addr1, addr2),
|
||||||
|
);
|
||||||
|
std::env::set_var("ASB__NETWORK__LISTEN", format!("{},{}", addr1, addr2));
|
||||||
|
|
||||||
|
let expected = Config {
|
||||||
|
data: Data { dir },
|
||||||
|
bitcoin: Bitcoin {
|
||||||
|
electrum_rpc_url: defaults.electrum_rpc_url,
|
||||||
|
target_block: defaults.bitcoin_confirmation_target,
|
||||||
|
finality_confirmations: None,
|
||||||
|
network: bitcoin::Network::Bitcoin,
|
||||||
|
},
|
||||||
|
network: Network {
|
||||||
|
listen,
|
||||||
|
rendezvous_point: None,
|
||||||
|
external_addresses,
|
||||||
|
},
|
||||||
|
monero: Monero {
|
||||||
|
wallet_rpc_url: defaults.monero_wallet_rpc_url,
|
||||||
|
finality_confirmations: None,
|
||||||
|
network: monero::Network::Mainnet,
|
||||||
|
},
|
||||||
|
tor: Default::default(),
|
||||||
|
maker: Maker {
|
||||||
|
min_buy_btc: bitcoin::Amount::from_btc(DEFAULT_MIN_BUY_AMOUNT).unwrap(),
|
||||||
|
max_buy_btc: bitcoin::Amount::from_btc(DEFAULT_MAX_BUY_AMOUNT).unwrap(),
|
||||||
|
ask_spread: Decimal::from_f64(DEFAULT_SPREAD).unwrap(),
|
||||||
|
price_ticker_ws_url: defaults.price_ticker_ws_url,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
initial_setup(config_path.clone(), expected.clone()).unwrap();
|
||||||
|
let actual = read_config(config_path).unwrap().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
std::env::remove_var("ASB__DATA__DIR");
|
||||||
|
std::env::remove_var("ASB__NETWORK__EXTERNAL_ADDRESSES");
|
||||||
|
std::env::remove_var("ASB__NETWORK__LISTEN");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user