commit 643cd6cf56acd87de54d2278ecfcf8c0266e3235
parent 7fce22cf8134ad6986070ca4ef41fe8a474f81b9
Author: Antoine A <>
Date: Tue, 8 Mar 2022 15:05:23 +0100
Better config parsing
Diffstat:
10 files changed, 126 insertions(+), 104 deletions(-)
diff --git a/btc-wire/src/bin/btc-wire-utils.rs b/btc-wire/src/bin/btc-wire-utils.rs
@@ -80,9 +80,8 @@ pub fn auto_wallet(rpc: &mut Rpc, config: &BitcoinConfig, name: &str) -> (Rpc, A
fn main() {
common::log::init();
let args = Args::parse();
- let (taler_config, currency) = load_taler_config(args.config.as_deref());
- let btc_config =
- BitcoinConfig::load(args.datadir.unwrap_or(taler_config.custom), currency).unwrap();
+ let (taler_config, path, currency) = load_taler_config(args.config.as_deref());
+ let btc_config = BitcoinConfig::load(args.datadir.unwrap_or(path), currency).unwrap();
let mut rpc = Rpc::common(&btc_config).unwrap();
match args.cmd {
@@ -118,7 +117,7 @@ fn main() {
}
Cmd::Resetdb => {
let hash: BlockHash = rpc.get_genesis().unwrap();
- let mut db = taler_config.db_config.connect(NoTls).unwrap();
+ let mut db = taler_config.db_config().connect(NoTls).unwrap();
let mut tx = db.transaction().unwrap();
// Clear transaction tables and reset state
tx.execute("DELETE FROM tx_in", &[]).unwrap();
diff --git a/btc-wire/src/lib.rs b/btc-wire/src/lib.rs
@@ -162,29 +162,28 @@ pub struct WireState {
impl WireState {
pub fn load_taler_config(file: Option<&Path>) -> Self {
- let (taler_config, currency) = load_taler_config(file);
- let btc_config = BitcoinConfig::load(taler_config.custom, currency)
- .expect("Failed to read bitcoin configuration file");
- let init_confirmation = taler_config.confirmation.unwrap_or(DEFAULT_CONFIRMATION) as u32;
+ let (taler_config, path, currency) = load_taler_config(file);
+ let btc_config =
+ BitcoinConfig::load(path, currency).expect("Failed to read bitcoin configuration file");
+ let init_confirmation = taler_config.confirmation().unwrap_or(DEFAULT_CONFIRMATION) as u32;
Self {
confirmation: AtomicU32::new(init_confirmation),
max_confirmation: init_confirmation * 2,
- btc_config,
- bounce_fee: config_bounce_fee(&taler_config.bounce_fee, currency),
- lifetime: taler_config.wire_lifetime,
- bump_delay: taler_config.bump_delay,
- base_url: taler_config.base_url,
- db_config: taler_config.db_config,
+ bounce_fee: config_bounce_fee(&taler_config.bounce_fee(), currency),
+ lifetime: taler_config.wire_lifetime(),
+ bump_delay: taler_config.bump_delay(),
+ base_url: taler_config.base_url(),
+ db_config: taler_config.db_config(),
currency,
+ btc_config,
}
}
}
// Load taler config with btc-wire specific config
-pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig<PathBuf>, CurrencyBtc) {
- let config = TalerConfig::load_with_custom(file, |dep| {
- common::config::path(dep, "CONF_PATH").unwrap_or_else(default_data_dir)
- });
+pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig, PathBuf, CurrencyBtc) {
+ let config = TalerConfig::load(file);
+ let path = config.path("CONF_PATH").unwrap_or_else(default_data_dir);
let currency = match config.currency {
Currency::BTC(it) => it,
_ => fail(format!(
@@ -192,7 +191,7 @@ pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig<PathBuf>, Currency
config.currency.to_str()
)),
};
- (config, currency)
+ (config, path, currency)
}
// Parse bitcoin amount from config bounce fee
diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs
@@ -64,16 +64,16 @@ fn main() {
fn init(config: Option<PathBuf>, init: Init) {
// Parse taler config
- let (taler_config, currency) = load_taler_config(config.as_deref());
+ let (taler_config, path, currency) = load_taler_config(config.as_deref());
// Connect to database
let mut db = taler_config
- .db_config
+ .db_config()
.connect(NoTls)
.expect("Failed to connect to database");
// Parse bitcoin config
- let btc_conf = BitcoinConfig::load(taler_config.custom, currency)
- .expect("Failed to load bitcoin configuration");
+ let btc_conf =
+ BitcoinConfig::load(path, currency).expect("Failed to load bitcoin configuration");
// Connect to bitcoin node
let mut rpc = Rpc::common(&btc_conf).expect("Failed to connect to bitcoin RPC server");
match init {
diff --git a/common/src/config.rs b/common/src/config.rs
@@ -28,33 +28,14 @@ use crate::{
pub use ini;
// Depolymerizer taler config
-pub struct TalerConfig<T> {
- // common
- pub db_config: postgres::Config,
+pub struct TalerConfig {
+ conf: Ini,
+ section_name: &'static str,
pub currency: Currency,
- pub base_url: Url,
- // wire-gateway
- pub http_lifetime: Option<u32>,
- pub port: u16,
- pub unix_path: Option<PathBuf>,
- // wire common
- pub confirmation: Option<u16>,
- pub bounce_fee: Option<String>,
- pub wire_lifetime: Option<u32>,
- pub bump_delay: Option<u32>,
- pub payto: Option<Url>,
- // custom config
- pub custom: T,
}
-impl TalerConfig<()> {
+impl TalerConfig {
pub fn load(file: Option<&Path>) -> Self {
- Self::load_with_custom(file, |_| {})
- }
-}
-
-impl<T> TalerConfig<T> {
- pub fn load_with_custom(file: Option<&Path>, lambda: fn(&Properties) -> T) -> Self {
// Load config using taler-config
let mut cmd = Command::new("taler-config");
cmd.arg("-d");
@@ -87,32 +68,75 @@ impl<T> TalerConfig<T> {
Currency::ETH(_) => "depolymerizer-ethereum",
};
- let dep = section(&conf, section_name);
Self {
- db_config: required(dep, "DB_URL", postgres),
+ conf,
+ section_name,
currency,
- base_url: required(section(&conf, "exchange"), "BASE_URL", url),
- confirmation: nb(dep, "CONFIRMATION"),
- bounce_fee: string(dep, "BOUNCE_FEE"),
- wire_lifetime: nb(dep, "WIRE_LIFETIME")
- .and_then(|nb| (nb != 0).then(|| Some(nb)))
- .unwrap_or(None),
- bump_delay: nb(dep, "BUMP_DELAY")
- .and_then(|nb| (nb != 0).then(|| Some(nb)))
- .unwrap_or(None),
- port: nb(dep, "PORT").unwrap_or(8080),
- unix_path: path(dep, "UNIXPATH"),
- payto: url(dep, "PAYTO"),
- http_lifetime: nb(dep, "HTTP_LIFETIME")
- .and_then(|nb| (nb != 0).then(|| Some(nb)))
- .unwrap_or(None),
- custom: lambda(dep),
}
}
- // Enforce payto requirement
- pub fn require_payto(&self) -> Url {
- expect_config(self.payto.clone(), "PAYTO")
+ fn section(&self) -> &Properties {
+ section(&self.conf, self.section_name)
+ }
+
+ fn non_zero_option(&self, name: &str) -> Option<u32> {
+ nb(self.section(), name)
+ .and_then(|nb| (nb != 0).then(|| Some(nb)))
+ .unwrap_or(None)
+ }
+}
+
+impl TalerConfig {
+ /* ----- Common ----- */
+
+ pub fn db_config(&self) -> postgres::Config {
+ required(self.section(), "DB_URL", postgres)
+ }
+
+ pub fn base_url(&self) -> Url {
+ required(section(&self.conf, "exchange"), "BASE_URL", url)
+ }
+
+ /* ----- Wire Gateway ----- */
+
+ pub fn payto(&self) -> Url {
+ required(self.section(), "PAYTO", url)
+ }
+
+ pub fn port(&self) -> u16 {
+ nb(self.section(), "PORT").unwrap_or(8080)
+ }
+
+ pub fn unix_path(&self) -> Option<PathBuf> {
+ path(self.section(), "UNIXPATH")
+ }
+
+ pub fn http_lifetime(&self) -> Option<u32> {
+ self.non_zero_option("HTTP_LIFETIME")
+ }
+
+ /* ----- Wire Common ----- */
+
+ pub fn confirmation(&self) -> Option<u16> {
+ nb(self.section(), "CONFIRMATION")
+ }
+
+ pub fn bounce_fee(&self) -> Option<String> {
+ string(self.section(), "BOUNCE_FEE")
+ }
+
+ pub fn wire_lifetime(&self) -> Option<u32> {
+ self.non_zero_option("WIRE_LIFETIME")
+ }
+
+ pub fn bump_delay(&self) -> Option<u32> {
+ self.non_zero_option("BUMP_DELAY")
+ }
+
+ /* ----- Custom ----- */
+
+ pub fn path(&self, name: &str) -> Option<PathBuf> {
+ path(self.section(), name)
}
}
diff --git a/eth-wire/src/bin/eth-wire-utils.rs b/eth-wire/src/bin/eth-wire-utils.rs
@@ -104,9 +104,9 @@ enum Cmd {
fn main() {
init();
let args: Args = Args::parse();
- let (taler_config, currency) = load_taler_config(args.config.as_deref());
+ let (taler_config, ipc_path, currency) = load_taler_config(args.config.as_deref());
- let ipc_path = args.datadir.unwrap_or(taler_config.custom);
+ let ipc_path = args.datadir.unwrap_or(ipc_path);
let mut rpc = Rpc::new(ipc_path).unwrap();
let passwd = password();
match args.cmd {
@@ -167,7 +167,7 @@ fn main() {
}
Cmd::Resetdb => {
let block = rpc.earliest_block().unwrap();
- let mut db = taler_config.db_config.connect(NoTls).unwrap();
+ let mut db = taler_config.db_config().connect(NoTls).unwrap();
let mut tx = db.transaction().unwrap();
// Clear transaction tables and reset state
tx.execute("DELETE FROM tx_in", &[]).unwrap();
diff --git a/eth-wire/src/lib.rs b/eth-wire/src/lib.rs
@@ -233,19 +233,19 @@ pub struct WireState {
impl WireState {
pub fn load_taler_config(file: Option<&Path>) -> Self {
- let (taler_config, currency) = load_taler_config(file);
- let init_confirmation = taler_config.confirmation.unwrap_or(DEFAULT_CONFIRMATION) as u32;
- let payto = taler_config.require_payto();
+ let (taler_config, ipc_path, currency) = load_taler_config(file);
+ let init_confirmation = taler_config.confirmation().unwrap_or(DEFAULT_CONFIRMATION) as u32;
+ let payto = taler_config.payto();
Self {
confirmation: AtomicU32::new(init_confirmation),
max_confirmations: init_confirmation * 2,
address: eth_payto_addr(&payto).unwrap(),
- ipc_path: taler_config.custom,
- bounce_fee: config_bounce_fee(&taler_config.bounce_fee, currency),
- lifetime: taler_config.wire_lifetime,
- bump_delay: taler_config.bump_delay,
- base_url: taler_config.base_url,
- db_config: taler_config.db_config,
+ ipc_path,
+ bounce_fee: config_bounce_fee(&taler_config.bounce_fee(), currency),
+ lifetime: taler_config.wire_lifetime(),
+ bump_delay: taler_config.bump_delay(),
+ base_url: taler_config.base_url(),
+ db_config: taler_config.db_config(),
payto,
currency,
}
@@ -253,10 +253,9 @@ impl WireState {
}
// Load taler config with eth-wire specific config
-pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig<PathBuf>, CurrencyEth) {
- let config = TalerConfig::load_with_custom(file, |dep| {
- common::config::path(dep, "IPC_PATH").unwrap_or_else(default_data_dir)
- });
+pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig, PathBuf, CurrencyEth) {
+ let config = TalerConfig::load(file);
+ let path = config.path("IPC_PATH").unwrap_or_else(default_data_dir);
let currency = match config.currency {
Currency::ETH(it) => it,
_ => fail(format!(
@@ -264,7 +263,7 @@ pub fn load_taler_config(file: Option<&Path>) -> (TalerConfig<PathBuf>, Currency
config.currency.to_str()
)),
};
- (config, currency)
+ (config, path, currency)
}
// Parse ethereum value from config bounce fee
diff --git a/eth-wire/src/main.rs b/eth-wire/src/main.rs
@@ -19,8 +19,9 @@ use std::path::PathBuf;
use clap::StructOpt;
use common::{named_spawn, password, postgres::NoTls, reconnect::auto_reconnect_db};
use eth_wire::{
+ load_taler_config,
rpc::{auto_rpc_common, auto_rpc_wallet, Rpc, RpcClient},
- SyncState, WireState, load_taler_config,
+ SyncState, WireState,
};
use ethereum_types::H160;
use loops::{analysis::analysis, watcher::watcher, worker::worker};
@@ -59,14 +60,14 @@ fn main() {
fn init(config: Option<PathBuf>, init: Init) {
// Parse taler config
- let (taler_config, _) = load_taler_config(config.as_deref());
+ let (taler_config, ipc_path, _) = load_taler_config(config.as_deref());
// Connect to database
let mut db = taler_config
- .db_config
+ .db_config()
.connect(NoTls)
.expect("Failed to connect to database");
// Connect to ethereum node
- let mut rpc = Rpc::new(taler_config.custom).expect("Failed to connect to ethereum RPC server");
+ let mut rpc = Rpc::new(ipc_path).expect("Failed to connect to ethereum RPC server");
match init {
Init::Initdb => {
diff --git a/instrumentation/src/main.rs b/instrumentation/src/main.rs
@@ -94,7 +94,7 @@ pub fn main() {
common::log::init();
let args = Args::parse();
let taler_config = TalerConfig::load(args.config.as_deref());
- let base_url = format!("http://localhost:{}", taler_config.port);
+ let base_url = format!("http://localhost:{}", taler_config.port());
match taler_config.currency {
Currency::BTC(_) => btc_test(args.config.as_deref(), &base_url),
diff --git a/makefile b/makefile
@@ -35,7 +35,7 @@ test_eth: install_test
test/eth/bumpfee.sh
test/eth/maxfee.sh
-test: test_gateway test_eth test_btc
+test: test_gateway test_btc test_eth
segwit_demo:
cargo run --release --bin segwit-demo
\ No newline at end of file
diff --git a/wire-gateway/src/main.rs b/wire-gateway/src/main.rs
@@ -109,17 +109,17 @@ async fn main() {
common::log::log::warn!("Running with test admin endpoint unsuitable for production");
// Parse postgres url
- let config = &taler_config.db_config;
+ let db_config = taler_config.db_config();
// TODO find a way to clean this ugly mess
let mut cfg = deadpool_postgres::Config::new();
- cfg.user = config.get_user().map(|it| it.to_string());
- cfg.password = config
+ cfg.user = db_config.get_user().map(|it| it.to_string());
+ cfg.password = db_config
.get_password()
.map(|it| String::from_utf8(it.to_vec()).unwrap());
- cfg.dbname = config.get_dbname().map(|it| it.to_string());
- cfg.options = config.get_options().map(|it| it.to_string());
+ cfg.dbname = db_config.get_dbname().map(|it| it.to_string());
+ cfg.options = db_config.get_options().map(|it| it.to_string());
cfg.host = Some(
- config
+ db_config
.get_hosts()
.iter()
.map(|it| match it {
@@ -129,18 +129,18 @@ async fn main() {
})
.collect(),
);
- cfg.ports = Some(config.get_ports().to_vec());
- cfg.application_name = config.get_application_name().map(|it| it.to_string());
- cfg.connect_timeout = config.get_connect_timeout().cloned();
+ cfg.ports = Some(db_config.get_ports().to_vec());
+ cfg.application_name = db_config.get_application_name().map(|it| it.to_string());
+ cfg.connect_timeout = db_config.get_connect_timeout().cloned();
let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
- let payto = taler_config.require_payto();
+ let payto = taler_config.payto();
let state = ServerState {
pool,
notify: Notify::new(),
- lifetime: taler_config.http_lifetime.map(AtomicU32::new),
+ lifetime: taler_config.http_lifetime().map(AtomicU32::new),
status: AtomicBool::new(true),
- db_config: taler_config.db_config,
+ db_config,
payto,
currency: taler_config.currency,
};
@@ -190,7 +190,7 @@ async fn main() {
if let Err(e) = server.await {
error!("server: {}", e);
}
- } else if let Some(path) = taler_config.unix_path {
+ } else if let Some(path) = taler_config.unix_path() {
use hyperlocal::UnixServerExt;
info!("Server listening on unix domain socket {:?}", path);
if let Err(err) = std::fs::remove_file(&path) {
@@ -206,7 +206,7 @@ async fn main() {
error!("server: {}", e);
}
} else {
- let addr = ([0, 0, 0, 0], taler_config.port).into();
+ let addr = ([0, 0, 0, 0], taler_config.port()).into();
info!("Server listening on http://{}", &addr);
let server = Server::bind(&addr)
.serve(make_service)