depolymerization

wire gateway for Bitcoin/Ethereum
Log | Files | Refs | Submodules | README | LICENSE

commit 5f97609307dd96c3b0dca2a5f61f914fb9057f96
parent 7f443715468c292d84c4a0c54942aab550120cfb
Author: Antoine A <>
Date:   Tue,  4 Jan 2022 20:25:02 +0100

Update dependencies and add support for unix domain socket

Diffstat:
M.gitignore | 4++--
MCargo.lock | 64++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mbtc-wire/Cargo.toml | 10+++++-----
Mbtc-wire/src/main.rs | 3+--
Mmakefile | 10+++++++---
Dscript/conf/taler_unix.conf | 12------------
Mscript/setup.sh | 18+++++++++---------
Mtaler-api/Cargo.toml | 4++--
Mtaler-config/src/lib.rs | 2+-
Mtaler-log/Cargo.toml | 2+-
Muri-pack/Cargo.toml | 4++--
Mwire-gateway/Cargo.toml | 10++++++----
Mwire-gateway/src/main.rs | 91++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
13 files changed, 143 insertions(+), 91 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,2 @@ /target -*.log -\ No newline at end of file +log +\ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock @@ -463,9 +463,9 @@ dependencies = [ [[package]] name = "flexi_logger" -version = "0.20.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ea44b8d87613dd188e316a6120dfe879f0c01489f55927b30ca068a67f4ae5" +checksum = "11be38a063886b7be57de89636d65c07d318c1f9bd985cd8ab2c343786a910bc" dependencies = [ "glob", "lazy_static", @@ -582,9 +582,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -641,6 +641,12 @@ dependencies = [ ] [[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] name = "hmac" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -707,6 +713,19 @@ dependencies = [ ] [[package]] +name = "hyperlocal" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fafdf7b2b2de7c9784f76e02c0935e65a8117ec3b768644379983ab333ac98c" +dependencies = [ + "futures-util", + "hex", + "hyper", + "pin-project", + "tokio", +] + +[[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -964,10 +983,30 @@ dependencies = [ ] [[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -1262,9 +1301,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -1281,9 +1320,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -1292,9 +1331,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ "itoa 1.0.1", "ryu", @@ -1822,6 +1861,7 @@ dependencies = [ "bitcoin", "deadpool-postgres", "hyper", + "hyperlocal", "listenfd", "miniz_oxide", "rand", diff --git a/btc-wire/Cargo.toml b/btc-wire/Cargo.toml @@ -14,16 +14,16 @@ bitcoin = { version = "0.27.1", features = [ "use-serde", ], default-features = false } # Cli args -argh = "0.1.6" +argh = "0.1.7" # Bech32 encoding and decoding bech32 = "0.8.1" # Secure random rand = { version = "0.8.4", features = ["getrandom"] } # Fast insecure random -fastrand = "1.5.0" +fastrand = "1.6.0" # Serialization library -serde = { version = "1.0.130", features = ["derive"] } -serde_json = "1.0.66" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" serde_repr = "0.1" # Error macros thiserror = "1.0.30" @@ -34,7 +34,7 @@ uri-pack = { path = "../uri-pack" } # Url format url = { version = "2.2.2", features = ["serde"] } # Ansi color -owo-colors = "3.1.1" +owo-colors = "3.2.0" base64 = "0.13.0" # Taler libs taler-api = { path = "../taler-api" } diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs @@ -12,7 +12,6 @@ use rand::{rngs::OsRng, RngCore}; use reconnect::{AutoReconnectRPC, AutoReconnectSql}; use std::{ collections::{HashMap, HashSet}, - path::PathBuf, process::exit, str::FromStr, time::{Duration, SystemTime}, @@ -455,7 +454,7 @@ fn main() { let data_dir = config .btc_data_dir .as_ref() - .map(|p| p.clone()) + .cloned() .unwrap_or_else(default_data_dir); let config: &'static Config = Box::leak(Box::new(config)); let btc_config = BitcoinConfig::load(&data_dir).unwrap(); diff --git a/makefile b/makefile @@ -2,10 +2,14 @@ install: cargo install --path btc-wire --bin btc-wire-cli btc-wire cargo install --path wire-gateway -test: +test_gateway: script/test_gateway.sh + +test_btc: script/test_btc_wire.sh script/test_btc_reconnect.sh script/test_btc_fail.sh script/test_btc_fork.sh - script/test_btc_stress.sh -\ No newline at end of file + script/test_btc_stress.sh + +test: test_gateway test_btc +\ No newline at end of file diff --git a/script/conf/taler_unix.conf b/script/conf/taler_unix.conf @@ -1,11 +0,0 @@ -[exchange] -BASE_URL = http://test.com - -[depolymerizer-bitcoin] -DB_URL = postgres://localhost:5454/postgres?user=postgres&password=password -UNIXPATH = /tmp/wire.sock -PAYTO = payto://bitcoin/bcrt1qgkgxkjj27g3f7s87mcvjjsghay7gh34cx39prj -CONFIRMATION = 3 -BTC_WALLET = wire -BTC_DATA_DIR = ~/.bitcoin -BOUNCE_FEE = 1000 -\ No newline at end of file diff --git a/script/setup.sh b/script/setup.sh @@ -22,7 +22,7 @@ BTC_DIR=$DIR/bitcoin BTC_DIR2=$DIR/bitcoin2 DB_DIR=$DIR/db CONF=$DIR/taler.conf -for dir in $BTC_DIR $BTC_DIR2 $DB_DIR; do +for dir in $BTC_DIR $BTC_DIR2 $DB_DIR log; do mkdir -p $dir done @@ -56,7 +56,7 @@ function reset_db() { function init_btc() { cp ${BASH_SOURCE%/*}/conf/bitcoin.conf $BTC_DIR/bitcoin.conf BTC_CLI="bitcoin-cli -datadir=$BTC_DIR" - bitcoind -datadir=$BTC_DIR &> btc.log & + bitcoind -datadir=$BTC_DIR &> log/btc.log & BTC_PID="$!" $BTC_CLI -rpcwait getnetworkinfo > /dev/null } @@ -65,7 +65,7 @@ function init_btc() { function init_btc2() { cp ${BASH_SOURCE%/*}/conf/bitcoin2.conf $BTC_DIR2/bitcoin.conf BTC_CLI2="bitcoin-cli -datadir=$BTC_DIR2" - bitcoind -datadir=$BTC_DIR2 &> btc2.log & + bitcoind -datadir=$BTC_DIR2 &> log/btc2.log & $BTC_CLI2 -rpcwait getnetworkinfo > /dev/null $BTC_CLI addnode 127.0.0.1:8346 onetry } @@ -84,7 +84,7 @@ function btc2_fork() { # Start a bitcoind regest server in a previously created temporary directory and load wallets function restart_btc() { - bitcoind -datadir=$BTC_DIR &>> btc.log & + bitcoind -datadir=$BTC_DIR &>> log/btc.log & $BTC_CLI -rpcwait getnetworkinfo > /dev/null for wallet in wire client reserve; do $BTC_CLI loadwallet $wallet > /dev/null @@ -143,22 +143,22 @@ function check_balance() { # Start btc_wire function btc_wire() { cargo build --bin btc-wire --release &> /dev/null - target/release/btc-wire $CONF &> btc_wire.log & + target/release/btc-wire $CONF &> log/btc_wire.log & WIRE_PID="$!" } # Start btc_wire with random failures function fail_btc_wire() { cargo build --bin btc-wire --release --features fail &> /dev/null - target/release/btc-wire $CONF &> btc_wire.log & + target/release/btc-wire $CONF &> log/btc_wire.log & WIRE_PID="$!" } # Start multiple btc_wire in parallel function stressed_btc_wire() { cargo build --bin btc-wire --release &> /dev/null - target/release/btc-wire $CONF &> btc_wire.log & - target/release/btc-wire $CONF &> btc_wire1.log & + target/release/btc-wire $CONF &> log/btc_wire.log & + target/release/btc-wire $CONF &> log/btc_wire1.log & } # ----- Gateway ------ # @@ -166,7 +166,7 @@ function stressed_btc_wire() { # Start wire_gateway in test mode function gateway() { cargo build --bin wire-gateway --release --features test &> /dev/null - target/release/wire-gateway $CONF &> gateway.log & + target/release/wire-gateway $CONF &> log/gateway.log & for n in `seq 1 50`; do echo -n "." sleep 0.2 diff --git a/taler-api/Cargo.toml b/taler-api/Cargo.toml @@ -7,11 +7,11 @@ edition = "2021" [dependencies] # Serialization framework -serde = { version = "1.0.130", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } # Serialization helper serde_with = "1.11.0" # JSON serialization -serde_json = "1.0.72" +serde_json = "1.0" # Url format url = { version = "2.2.2", features = ["serde"] } # Crockford’s base32 diff --git a/taler-config/src/lib.rs b/taler-config/src/lib.rs @@ -69,6 +69,6 @@ fn nb<T: FromStr>(properties: &Properties, name: &str) -> Option<T> { fn url(properties: &Properties, name: &str) -> Option<Url> { properties.get(name).map(|s| { - Url::parse(&s).unwrap_or_else(|_| panic!("config value {} is not a valid url", name)) + Url::parse(s).unwrap_or_else(|_| panic!("config value {} is not a valid url", name)) }) } diff --git a/taler-log/Cargo.toml b/taler-log/Cargo.toml @@ -5,5 +5,5 @@ edition = "2021" [dependencies] log = "0.4.14" -flexi_logger = { version = "0.20.1", default-features = false } +flexi_logger = { version = "0.22.0", default-features = false } time = { version = "0.3.5", features = ["formatting", "macros"] } diff --git a/uri-pack/Cargo.toml b/uri-pack/Cargo.toml @@ -12,13 +12,13 @@ csv = "1.1.6" [dev-dependencies] # Json parser -serde_json = "1.0.72" +serde_json = "1.0" # Url parser url = "2.2.2" # statistics-driven micro-benchmarks criterion = "0.3.5" # Fast insecure random -fastrand = "1.5.0" +fastrand = "1.6.0" # Fuzzing test quickcheck = "1.0.3" quickcheck_macros = "1.0.0" diff --git a/wire-gateway/Cargo.toml b/wire-gateway/Cargo.toml @@ -9,15 +9,17 @@ test = [] [dependencies] # Http library -hyper = { version = "0.14.15", features = ["http1", "server", "runtime"] } +hyper = { version = "0.14.16", features = ["http1", "server", "runtime"] } +# Hyper compat lib for unix domain socket +hyperlocal = "0.8.0" # Async runtime -tokio = { version = "1.14.0", features = ["net", "macros", "rt-multi-thread"] } +tokio = { version = "1.15.0", features = ["net", "macros", "rt-multi-thread"] } # Serialization framework -serde = { version = "1.0.130", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } # Serialization helper serde_with = "1.11.0" # JSON serialization -serde_json = "1.0.72" +serde_json = "1.0" # Url query serialization serde_urlencoded = "0.7.0" # Error macros diff --git a/wire-gateway/src/main.rs b/wire-gateway/src/main.rs @@ -32,7 +32,9 @@ struct ServerState { async fn main() { taler_log::init(); - let conf = taler_config::Config::load_from_file(std::env::args_os().nth(1).expect("Missing conf path arg")); + let conf = taler_config::Config::load_from_file( + std::env::args_os().nth(1).expect("Missing conf path arg"), + ); #[cfg(feature = "test")] taler_log::log::warn!("Running with test admin endpoint unsuitable for production"); @@ -63,52 +65,69 @@ async fn main() { cfg.connect_timeout = config.get_connect_timeout().cloned(); let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap(); - let state = ServerState { pool, config: conf }; + let state = ServerState { + pool, + config: conf.clone(), + }; let state: &'static ServerState = Box::leak(Box::new(state)); - let make_service = make_service_fn(move |_| async move { - Ok::<_, Infallible>(service_fn(move |req| async move { - let start = Instant::now(); - let (parts, body) = req.into_parts(); - let (response, msg) = match router(&parts, body, state).await { - Ok(resp) => (resp, String::new()), - Err(err) => err.response(), - }; - let status = response.status().as_u16(); - let level = if status >= 500 { - Level::Error - } else if status >= 400 { - Level::Warn - } else { - Level::Info - }; - log!( - level, - "{} {} {}ms {} - {}", - parts.method, - status, - start.elapsed().as_millis(), - parts.uri.path(), - msg - ); - Ok::<Response<Body>, Infallible>(response) - })) + let service = service_fn(move |req| async move { + let start = Instant::now(); + let (parts, body) = req.into_parts(); + let (response, msg) = match router(&parts, body, state).await { + Ok(resp) => (resp, String::new()), + Err(err) => err.response(), + }; + let status = response.status().as_u16(); + let level = if status >= 500 { + Level::Error + } else if status >= 400 { + Level::Warn + } else { + Level::Info + }; + log!( + level, + "{} {} {}ms {} - {}", + parts.method, + status, + start.elapsed().as_millis(), + parts.uri.path(), + msg + ); + Ok::<Response<Body>, Infallible>(response) }); + let make_service = make_service_fn(move |_| async move { Ok::<_, Infallible>(service) }); + let make_service_unix = make_service_fn(move |_| async move { Ok::<_, Infallible>(service) }); let mut listenfd = ListenFd::from_env(); - let server = if let Some(listener) = listenfd.take_tcp_listener(0).unwrap() { + if let Some(listener) = listenfd.take_tcp_listener(0).unwrap() { info!( "Server listening on activated socket {}", listener.local_addr().unwrap() ); - Server::from_tcp(listener).unwrap().serve(make_service) + let server = Server::from_tcp(listener).unwrap().serve(make_service); + if let Err(e) = server.await { + error!("server: {}", e); + } + } else if let Some(path) = conf.unix_path { + use hyperlocal::UnixServerExt; + info!("Server listening on unix domain socket {:?}", path); + if let Err(err) = std::fs::remove_file(&path) { + if err.kind() != std::io::ErrorKind::NotFound { + panic!("{}", err); + } + } + let server = Server::bind_unix(path).unwrap().serve(make_service_unix); + if let Err(e) = server.await { + error!("server: {}", e); + } } else { let addr = ([0, 0, 0, 0], state.config.port).into(); info!("Server listening on http://{}", &addr); - Server::bind(&addr).serve(make_service) - }; - - if let Err(e) = server.await { - error!("server: {}", e); + let server = Server::bind(&addr).serve(make_service); + if let Err(e) = server.await { + error!("server: {}", e); + } } }