depolymerization

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

commit eb3e74799c61d08e1fd56fea4e8f6f96593bf7cf
parent 4a34d2b574092d2e3f2f20c6b1b0909f9def4867
Author: Antoine A <>
Date:   Fri, 28 Mar 2025 13:45:01 +0100

common: update dependencies

Diffstat:
MCargo.lock | 159+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
MCargo.toml | 2+-
Mbtc-wire/src/bin/segwit-demo.rs | 4++--
Mbtc-wire/src/lib.rs | 28+++++++++++++++++++---------
Mbtc-wire/src/segwit.rs | 13++++++++-----
Mcommon/Cargo.toml | 5++---
Mcommon/src/lib.rs | 4++--
Minstrumentation/Cargo.toml | 4++--
Minstrumentation/src/gateway.rs | 19++++---------------
Minstrumentation/src/utils.rs | 32+++++++++++++++++++++-----------
10 files changed, 189 insertions(+), 81 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -110,6 +110,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] name = "async-trait" version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -205,6 +211,16 @@ dependencies = [ ] [[package]] +name = "base58ck" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals", + "bitcoin_hashes", +] + +[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -218,24 +234,21 @@ checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bech32" -version = "0.10.0-beta" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" - -[[package]] -name = "bech32" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" [[package]] name = "bitcoin" -version = "0.31.2" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" dependencies = [ - "bech32 0.10.0-beta", + "base58ck", + "bech32", "bitcoin-internals", + "bitcoin-io", + "bitcoin-units", "bitcoin_hashes", "hex-conservative", "hex_lit", @@ -245,20 +258,36 @@ dependencies = [ [[package]] name = "bitcoin-internals" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" +checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" dependencies = [ "serde", ] [[package]] -name = "bitcoin_hashes" -version = "0.13.0" +name = "bitcoin-io" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin-units" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" dependencies = [ "bitcoin-internals", + "serde", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", "hex-conservative", "serde", ] @@ -285,7 +314,7 @@ dependencies = [ name = "btc-wire" version = "0.1.0" dependencies = [ - "bech32 0.11.0", + "bech32", "bitcoin", "clap", "common", @@ -430,9 +459,9 @@ dependencies = [ [[package]] name = "color-backtrace" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "150fd80a270c0671379f388c8204deb6a746bb4eac8a6c03fe2460b2c0127ea0" +checksum = "2123a5984bd52ca861c66f66a9ab9883b27115c607f801f86c1bc2a84eb69f0f" dependencies = [ "backtrace", "termcolor", @@ -452,7 +481,7 @@ dependencies = [ "flexi_logger", "log", "postgres", - "rand 0.8.5", + "rand 0.9.0", "rust-ini", "serde", "serde_json", @@ -528,6 +557,35 @@ dependencies = [ ] [[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "indexmap 2.8.0", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -808,6 +866,15 @@ dependencies = [ ] [[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] name = "dotenvy" version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1218,9 +1285,12 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-conservative" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] [[package]] name = "hex_lit" @@ -1713,6 +1783,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2445,9 +2521,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "secp256k1" -version = "0.28.2" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "bitcoin_hashes", "secp256k1-sys", @@ -2456,9 +2532,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -2950,7 +3026,7 @@ dependencies = [ [[package]] name = "taler-api" version = "0.0.0" -source = "git+https://git.taler.net/taler-rust.git/#972b180ea70eb4cb129abb293379ab590ba3c2da" +source = "git+https://git.taler.net/taler-rust.git/#da9595df60f33c7ba76d1ad8f37f9505155093c0" dependencies = [ "axum", "dashmap", @@ -2972,7 +3048,7 @@ dependencies = [ [[package]] name = "taler-common" version = "0.0.0" -source = "git+https://git.taler.net/taler-rust.git/#972b180ea70eb4cb129abb293379ab590ba3c2da" +source = "git+https://git.taler.net/taler-rust.git/#da9595df60f33c7ba76d1ad8f37f9505155093c0" dependencies = [ "anyhow", "clap", @@ -3362,23 +3438,38 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "4b0351ca625c7b41a8e4f9bb6c5d9755f67f62c2187ebedecacd9974674b271d" dependencies = [ "base64", + "cookie_store", "flate2", "log", - "once_cell", + "percent-encoding", "rustls", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", - "url", + "ureq-proto", + "utf-8", "webpki-roots", ] [[package]] +name = "ureq-proto" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae239d0a3341aebc94259414d1dc67cfce87d41cbebc816772c91b77902fafa4" +dependencies = [ + "base64", + "http", + "httparse", + "log", +] + +[[package]] name = "uri-pack" version = "0.1.0" dependencies = [ @@ -3405,6 +3496,12 @@ dependencies = [ ] [[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] name = "utf16_iter" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -34,7 +34,7 @@ sqlx = { version = "0.8", features = [ url = { version = "2.2", features = ["serde"] } taler-common = { git = "https://git.taler.net/taler-rust.git/" } taler-api = { git = "https://git.taler.net/taler-rust.git/" } -bitcoin = { version = "0.31.2", features = [ +bitcoin = { version = "0.32.5", features = [ "std", "serde", ], default-features = false } diff --git a/btc-wire/src/bin/segwit-demo.rs b/btc-wire/src/bin/segwit-demo.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use bech32::Hrp; use bitcoin::{Address, Amount, Network}; -use btc_wire::segwit::decode_segwit_msg; +use btc_wire::{guess_network, segwit::decode_segwit_msg}; use btc_wire::{rpc_utils, segwit::encode_segwit_addr}; use common::{rand_slice, taler_common::types::base32}; @@ -49,7 +49,7 @@ pub fn main() { hex::encode(&second_half) ); // bech32: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki - let hrp = match address.network() { + let hrp = match guess_network(&address) { Network::Bitcoin => "bc", Network::Testnet | Network::Signet => "tb", Network::Regtest => "bcrt", diff --git a/btc-wire/src/lib.rs b/btc-wire/src/lib.rs @@ -62,7 +62,8 @@ impl Rpc { amount: &Amount, metadata: &[u8; 32], ) -> rpc::Result<Txid> { - let hrp = match to.network() { + let network = guess_network(to); + let hrp = match network { Network::Bitcoin => bech32::hrp::BC, Network::Testnet | Network::Signet => bech32::hrp::TB, Network::Regtest => bech32::hrp::BCRT, @@ -70,14 +71,8 @@ impl Rpc { }; let addresses = encode_segwit_key(hrp, metadata); let addresses = [ - Address::from_str(&addresses[0]) - .unwrap() - .require_network(*to.network()) - .unwrap(), - Address::from_str(&addresses[1]) - .unwrap() - .require_network(*to.network()) - .unwrap(), + Address::from_str(&addresses[0]).unwrap().assume_checked(), + Address::from_str(&addresses[1]).unwrap().assume_checked(), ]; let mut recipients = vec![(to, amount)]; let min = segwit_min_amount(); @@ -232,3 +227,18 @@ fn check_network_currency(network: Network, currency: CurrencyBtc) { )) } } + +pub fn guess_network(address: &Address) -> Network { + let addr = address.as_unchecked(); + for network in [ + Network::Bitcoin, + Network::Regtest, + Network::Signet, + Network::Regtest, + ] { + if addr.is_valid_for_network(network) { + return network; + } + } + unreachable!() +} diff --git a/btc-wire/src/segwit.rs b/btc-wire/src/segwit.rs @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2025 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -14,9 +14,11 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ use bech32::Hrp; -use common::{rand::rngs::OsRng, rand_slice}; +use common::{rand::rngs::ThreadRng, rand_slice}; use std::cmp::Ordering; +/// TODO use segwit v1 to only use a single address + /// Encode metadata into a segwit address pub fn encode_segwit_addr(hrp: Hrp, metada: &[u8; 20]) -> String { bech32::segwit::encode_v0(hrp, metada).unwrap() @@ -129,14 +131,14 @@ pub fn rand_addresses(hrp: Hrp, key: &[u8; 32]) -> Vec<String> { let mut addresses = encode_segwit_key(hrp, key).to_vec(); addresses.append(&mut rng_address); - addresses.shuffle(&mut OsRng); + addresses.shuffle(&mut ThreadRng::default()); addresses } #[cfg(test)] mod test { use common::{ - rand::{prelude::SliceRandom, rngs::OsRng}, + rand::{prelude::SliceRandom, rngs::ThreadRng}, rand_slice, }; @@ -144,10 +146,11 @@ mod test { #[test] fn test_shuffle() { + let mut rng = ThreadRng::default(); for _ in 0..1000 { let key = rand_slice(); let mut addresses = encode_segwit_key(bech32::hrp::TB, &key); - addresses.shuffle(&mut OsRng); + addresses.shuffle(&mut rng); let decoded = decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>()) .unwrap(); diff --git a/common/Cargo.toml b/common/Cargo.toml @@ -26,7 +26,7 @@ log = "0.4.20" # Postgres client postgres = "0.19.7" # Secure random -rand = { version = "0.8.5", features = ["getrandom"] } +rand = { version = "0.9.0" } # Securely zero memory zeroize = "1.6.0" # Optimized uri binary format @@ -35,4 +35,4 @@ uri-pack = { path = "../uri-pack" } exponential-backoff = "1.2.0" taler-common.workspace = true taler-api.workspace = true -sqlx.workspace = true -\ No newline at end of file +sqlx.workspace = true diff --git a/common/src/lib.rs b/common/src/lib.rs @@ -16,7 +16,7 @@ use std::{process::exit, thread::JoinHandle}; use ::log::error; -use rand::{RngCore, rngs::OsRng}; +use rand::{RngCore, rngs::ThreadRng}; use zeroize::Zeroizing; pub use postgres; @@ -35,7 +35,7 @@ pub mod status; /// Secure random slice generator using getrandom pub fn rand_slice<const N: usize>() -> [u8; N] { let mut slice = [0; N]; - OsRng.fill_bytes(&mut slice); + ThreadRng::default().fill_bytes(&mut slice); slice } diff --git a/instrumentation/Cargo.toml b/instrumentation/Cargo.toml @@ -19,7 +19,7 @@ eth-wire = { path = "../eth-wire" } ethereum-types.workspace = true hex.workspace = true # Wire Gateway -ureq = { version = "2.5.0", features = ["json"] } +ureq = { version = "3.0.0", features = ["json"] } # In memory deflate library libdeflater = "1.19.0" # Generate temporary files @@ -29,7 +29,7 @@ fastrand = "2.0.1" # terminal color owo-colors = "4.0.0" # Better backtrace -color-backtrace = "0.6.0" +color-backtrace = "0.7.0" # Send signal to child processes signal-child = "1.0.5" # Edit toml files diff --git a/instrumentation/src/gateway.rs b/instrumentation/src/gateway.rs @@ -26,11 +26,10 @@ use common::taler_common::{ }, }; use libdeflater::{CompressionLvl, Compressor}; -use ureq::Response; use crate::{ btc::BtcCtx, - utils::{TestCtx, cmd_out, cmd_redirect_ok, gateway_error}, + utils::{TestCtx, cmd_out, cmd_redirect_ok, gateway_error, http_code}, }; fn client_transfer(gateway_url: &str, payto_url: &PaytoURI, amount: &str) -> String { @@ -40,16 +39,6 @@ fn client_transfer(gateway_url: &str, payto_url: &PaytoURI, amount: &str) -> Str ) } -fn http_code(response: Result<Response, ureq::Error>) -> u16 { - match response { - Ok(resp) => resp.status(), - Err(err) => match err { - ureq::Error::Status(err, _) => err, - ureq::Error::Transport(_) => unreachable!(), - }, - } -} - /// Test wire-gateway conformance to documentation and its security pub fn api(ctx: TestCtx) { ctx.step("Setup"); @@ -184,7 +173,7 @@ pub fn api(ctx: TestCtx) { assert_eq!( http_code( ureq::post(&format!("{}transfer", ctx.gateway_url)) - .set("Content-Length", "1024") + .header("Content-Length", "1024") .send_json(&big_hello) ), 400 @@ -200,8 +189,8 @@ pub fn api(ctx: TestCtx) { assert_eq!( http_code( ureq::post(&format!("{}transfer", ctx.gateway_url)) - .set("Content-Encoding", "deflate") - .send_bytes(&compressed) + .header("Content-Encoding", "deflate") + .send(&compressed) ), 400 ); diff --git a/instrumentation/src/utils.rs b/instrumentation/src/utils.rs @@ -37,6 +37,7 @@ use common::{ }; use indicatif::ProgressBar; use tempfile::TempDir; +use ureq::http::Response; pub fn print_now(disp: impl Display) { print!("{}", disp); @@ -45,7 +46,7 @@ pub fn print_now(disp: impl Display) { #[must_use] pub fn check_incoming(base_url: &str, txs: &[([u8; 32], Amount)]) -> bool { - let res = ureq::get(&format!("{}history/incoming", base_url)) + let mut res = ureq::get(&format!("{}history/incoming", base_url)) .query("delta", &format!("-{}", txs.len())) .call() .unwrap(); @@ -55,7 +56,7 @@ pub fn check_incoming(base_url: &str, txs: &[([u8; 32], Amount)]) -> bool { if res.status() != 200 { return false; } - let history: IncomingHistory = res.into_json().unwrap(); + let history: IncomingHistory = res.body_mut().read_json().unwrap(); history.incoming_transactions.len() == txs.len() && txs.iter().all(|(reserve_pub_key, taler_amount)| { @@ -73,21 +74,30 @@ pub fn check_incoming(base_url: &str, txs: &[([u8; 32], Amount)]) -> bool { } } -pub fn gateway_error(path: &str, error: u16) { - let err = ureq::get(path).call().unwrap_err(); - match err { - ureq::Error::Status(nb, _) => assert_eq!(nb, error), - ureq::Error::Transport(_) => unreachable!(), +pub fn http_code<T>(response: Result<Response<T>, ureq::Error>) -> u16 { + match response { + Ok(resp) => resp.status().as_u16(), + Err(err) => match err { + ureq::Error::StatusCode(err) => err, + _ => unreachable!(), + }, } } +pub fn gateway_error(path: &str, error: u16) { + assert!(matches!( + ureq::get(path).call(), + Err(ureq::Error::StatusCode(err)) if err == error + )) +} + #[must_use] pub fn check_gateway_error(base_url: &str) -> bool { matches!( ureq::get(&format!("{}history/incoming", base_url)) .query("delta", "-5") .call(), - Err(ureq::Error::Status(504, _)) + Err(ureq::Error::StatusCode(504)) ) } @@ -97,7 +107,7 @@ pub fn check_gateway_down(base_url: &str) -> bool { ureq::get(&format!("{}history/incoming", base_url)) .query("delta", "-5") .call(), - Err(ureq::Error::Status(502, _)) + Err(ureq::Error::StatusCode(502)) ) } @@ -126,7 +136,7 @@ pub fn transfer( #[must_use] pub fn check_outgoing(base_url: &str, url: &Url, txs: &[([u8; 32], Amount)]) -> bool { - let res = ureq::get(&format!("{}history/outgoing", base_url)) + let mut res = ureq::get(&format!("{}history/outgoing", base_url)) .query("delta", &format!("-{}", txs.len())) .call() .unwrap(); @@ -136,7 +146,7 @@ pub fn check_outgoing(base_url: &str, url: &Url, txs: &[([u8; 32], Amount)]) -> if res.status() != 200 { return false; } - let history: OutgoingHistory = res.into_json().unwrap(); + let history: OutgoingHistory = res.body_mut().read_json().unwrap(); history.outgoing_transactions.len() == txs.len() && txs.iter().all(|(wtid, amount)| {