depolymerization

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

commit 4e5d68301bbfafd4db9ee045c9575dc46dd66257
parent eb3e74799c61d08e1fd56fea4e8f6f96593bf7cf
Author: Antoine A <>
Date:   Fri,  4 Apr 2025 10:31:23 +0200

common: clean code

Diffstat:
MCargo.lock | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mbtc-wire/src/lib.rs | 6+++---
Mbtc-wire/src/loops/worker.rs | 91+++++++++++++++++++++++++-------------------------------------------------------
Mbtc-wire/src/main.rs | 2+-
Mbtc-wire/src/segwit.rs | 14++++++++------
Mcommon/src/metadata.rs | 18++++++++++--------
Mcommon/src/sql.rs | 14+++++++++++++-
Meth-wire/src/lib.rs | 9++++++---
Meth-wire/src/loops/worker.rs | 35++++++++++++++---------------------
Minstrumentation/src/btc.rs | 90++++++++++++++++++++++++++++++++++++++++----------------------------------------
Minstrumentation/src/eth.rs | 101++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Minstrumentation/src/utils.rs | 40++++++++++++++++++++--------------------
12 files changed, 285 insertions(+), 247 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -143,9 +143,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" +checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" dependencies = [ "axum-core", "bytes", @@ -177,12 +177,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", @@ -409,9 +409,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -759,9 +759,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -769,9 +769,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", @@ -783,9 +783,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", @@ -1043,9 +1043,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -1392,9 +1392,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-util", @@ -1408,9 +1408,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.62" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1834,9 +1834,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" dependencies = [ "adler2", ] @@ -1932,9 +1932,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2806eaa3524762875e21c3dcd057bc4b7bfa01ce4da8d46be1cd43649e1cc6b" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -2440,9 +2440,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags", "errno", @@ -2728,9 +2728,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3026,7 +3026,7 @@ dependencies = [ [[package]] name = "taler-api" version = "0.0.0" -source = "git+https://git.taler.net/taler-rust.git/#da9595df60f33c7ba76d1ad8f37f9505155093c0" +source = "git+https://git.taler.net/taler-rust.git/#1dac9a6c47ee1e023087cfb6bff2946011bd42d3" dependencies = [ "axum", "dashmap", @@ -3048,7 +3048,7 @@ dependencies = [ [[package]] name = "taler-common" version = "0.0.0" -source = "git+https://git.taler.net/taler-rust.git/#da9595df60f33c7ba76d1ad8f37f9505155093c0" +source = "git+https://git.taler.net/taler-rust.git/#1dac9a6c47ee1e023087cfb6bff2946011bd42d3" dependencies = [ "anyhow", "clap", @@ -3705,11 +3705,37 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -3719,6 +3745,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + +[[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/btc-wire/src/lib.rs b/btc-wire/src/lib.rs @@ -21,9 +21,9 @@ use btc_config::BitcoinConfig; use common::{ config::TalerConfig, currency::{Currency, CurrencyBtc}, - log::{OrFail, fail}, + log::{fail, OrFail}, postgres, - taler_common::types::amount::Amount as TalerAmount, + taler_common::{api_common::EddsaPublicKey, types::amount::Amount as TalerAmount}, url::Url, }; use rpc::{Category, Rpc, Transaction}; @@ -84,7 +84,7 @@ impl Rpc { pub fn get_tx_segwit_key( &mut self, id: &Txid, - ) -> Result<(Transaction, [u8; 32]), GetSegwitErr> { + ) -> Result<(Transaction, EddsaPublicKey), GetSegwitErr> { let full = self.get_tx(id)?; let addresses: Vec<String> = full diff --git a/btc-wire/src/loops/worker.rs b/btc-wire/src/loops/worker.rs @@ -30,9 +30,9 @@ use common::{ metadata::OutMetadata, postgres, reconnect::AutoReconnectDb, - sql::{sql_array, sql_url}, + sql::{sql_base_32, sql_url}, status::{BounceStatus, DebitStatus}, - taler_common::types::{base32::Base32, timestamp::Timestamp}, + taler_common::{api_common::ShortHashCode, types::timestamp::Timestamp}, }; use postgres::{Client, fallible_iterator::FallibleIterator}; @@ -116,14 +116,8 @@ pub fn worker(mut rpc: AutoRpcWallet, mut db: AutoReconnectDb, mut state: WireSt &id.as_byte_array().as_slice(), ], )?; - let wtid: &[u8] = row.get(0); - let wtid: [u8; 32] = wtid.try_into().unwrap(); - info!( - ">> (bump) {} replace {} with {}", - Base32::from(wtid), - id, - bump.txid - ); + let wtid: ShortHashCode = sql_base_32(&row, 0); + info!(">> (bump) {wtid} replace {id} with {}", bump.txid); } // Send requested bounce @@ -133,7 +127,7 @@ pub fn worker(mut rpc: AutoRpcWallet, mut db: AutoReconnectDb, mut state: WireSt Ok(()) })(); if let Err(e) = result { - error!("worker: {}", e); + error!("worker: {e}"); // When we catch an error, we sometimes want to retry immediately (eg. reconnect to RPC or DB). // Bitcoin error codes are generic. We need to match the msg to get precise ones. Some errors // can resolve themselves when a new block is mined (new fees, new transactions). Our simple @@ -304,17 +298,10 @@ fn sync_chain_removed( if !blocking_bounce.is_empty() || !blocking_debit.is_empty() { let mut buf = "The following transaction have been removed from the blockchain, bitcoin backing is compromised until the transaction reappear:".to_string(); for (key, id, addr) in blocking_debit { - write!( - &mut buf, - "\n\tcredit {} in {} from {}", - Base32::from(key), - id, - addr - ) - .unwrap(); + write!(&mut buf, "\n\tcredit {key} in {id} from {addr}",).unwrap(); } for (id, bounced) in blocking_bounce { - write!(&mut buf, "\n\tbounced {} in {}", id, bounced).unwrap(); + write!(&mut buf, "\n\tbounced {id} in {bounced}").unwrap(); } error!("{}", buf); Ok(false) @@ -340,13 +327,7 @@ fn sync_chain_incoming_confirmed( &((full.time * 1000000) as i64), &(amount.val as i64), &(amount.frac as i32), &reserve_pub.as_slice(), &btc_payto_url(&debit_addr).raw(), &btc_payto_url(&credit_addr).raw() ])?; if nb > 0 { - info!( - "<< {} {} in {} from {}", - amount, - Base32::from(reserve_pub), - id, - debit_addr - ); + info!("<< {amount} {reserve_pub} in {id} from {debit_addr}"); } } Err(err) => match err { @@ -367,7 +348,7 @@ fn sync_chain_incoming_confirmed( fn sync_chain_debit( id: &Txid, full: &Transaction, - wtid: &[u8; 32], + wtid: &ShortHashCode, rpc: &mut Rpc, db: &mut Client, confirmations: i32, @@ -387,10 +368,7 @@ fn sync_chain_debit( ], )?; if nb_row > 0 { - warn!( - ">> (conflict) {} in {id} to {credit_addr}", - Base32::from(*wtid) - ); + warn!(">> (conflict) {wtid} in {id} to {credit_addr}"); } } } else { @@ -415,10 +393,7 @@ fn sync_chain_debit( ], )?; if nb_row > 0 { - warn!( - ">> (recovered) {amount} {} in {id} to {credit_addr}", - Base32::from(*wtid) - ); + warn!(">> (recovered) {amount} {wtid} in {id} to {credit_addr}"); } } DebitStatus::Sent => { @@ -433,10 +408,7 @@ fn sync_chain_debit( ], )?; if nb_row > 0 { - info!( - ">> (recovered) {} replace {txid} with {id}", - Base32::from(*wtid) - ); + info!(">> (recovered) {wtid} replace {txid} with {id}",); } } } @@ -450,10 +422,7 @@ fn sync_chain_debit( &[&((full.time*1000000) as i64), &(amount.val as i64), &(amount.frac as i32), &wtid.as_slice(), &btc_payto_url(&debit_addr).raw(), &btc_payto_url(&credit_addr).raw(), &state.base_url.as_ref(), &(DebitStatus::Sent as i16), &id.as_byte_array().as_slice(), &None::<&[u8]>], )?; if nb > 0 { - warn!( - ">> (onchain) {amount} {} in {id} to {credit_addr}", - Base32::from(*wtid) - ); + warn!(">> (onchain) {amount} {wtid} in {id} to {credit_addr}",); } } @@ -490,7 +459,7 @@ fn sync_chain_bounce( ], )?; if nb_row > 0 { - warn!("|| (conflict) {} in {}", &bounced, &id); + warn!("|| (conflict) {bounced} in {id}"); } } else { // Get previous bounce @@ -514,13 +483,12 @@ fn sync_chain_bounce( ], )?; if nb_row > 0 { - warn!("|| (recovered) {} in {}", &bounced, &id); + warn!("|| (recovered) {bounced} in {id}"); } } - BounceStatus::Ignored => error!( - "watcher: ignored bounce {} found in chain at {}", - bounced, id - ), + BounceStatus::Ignored => { + error!("watcher: ignored bounce {bounced} found in chain at {id}") + } BounceStatus::Sent => { /* Status is correct */ } } } else { @@ -530,7 +498,7 @@ fn sync_chain_bounce( &[&Timestamp::now().as_sql_micros(), &bounced.as_byte_array().as_slice(), &id.as_byte_array().as_slice(), &(BounceStatus::Sent as i16)], )?; if nb > 0 { - warn!("|| (onchain) {} in {}", &bounced, &id); + warn!("|| (onchain) {bounced} in {id}"); } } } @@ -558,7 +526,7 @@ fn sync_chain_outgoing( sync_chain_bounce(id, &Txid::from_byte_array(bounced), db, confirmations)? } }, - Ok((_, Err(e))) => warn!("send: decode-info {} - {}", id, e), + Ok((_, Err(e))) => warn!("send: decode-info {id} - {e}"), Err(e) => match e { GetOpReturnErr::MissingOpReturn => { /* Ignore */ } GetOpReturnErr::RPC(e) => return Err(e)?, @@ -577,10 +545,13 @@ fn debit(db: &mut Client, rpc: &mut Rpc, state: &WireState) -> LoopResult<bool> if let Some(row) = &row { let id: i64 = row.get(0); let amount = sql_btc_amount(row, 1, state.currency); - let wtid: [u8; 32] = sql_array(row, 3); + let wtid: ShortHashCode = sql_base_32(row, 3); let addr = sql_addr(row, 4); let url = sql_url(row, 5); - let metadata = OutMetadata::Debit { wtid, url }; + let metadata = OutMetadata::Debit { + wtid: wtid.clone(), + url, + }; let tx_id = rpc.send( &addr, @@ -598,13 +569,7 @@ fn debit(db: &mut Client, rpc: &mut Rpc, state: &WireState) -> LoopResult<bool> ], )?; let amount = btc_to_taler(&amount.to_signed().unwrap(), state.currency); - info!( - ">> {} {} in {} to {}", - amount, - Base32::from(wtid), - tx_id, - addr - ); + info!(">> {amount} {wtid} in {tx_id} to {addr}"); } Ok(row.is_some()) } @@ -638,7 +603,7 @@ fn bounce(db: &mut Client, rpc: &mut Rpc, fee: &BtcAmount) -> LoopResult<bool> { &id, ], )?; - info!("|| {} in {}", &bounced, &it); + info!("|| {bounced} in {it}"); } Err(err) => match err { rpc::Error::RPC { @@ -649,7 +614,7 @@ fn bounce(db: &mut Client, rpc: &mut Rpc, fee: &BtcAmount) -> LoopResult<bool> { "UPDATE bounce SET status=$1 WHERE id=$2", &[&(BounceStatus::Ignored as i16), &id], )?; - info!("|| (ignore) {} because {}", &bounced, msg); + info!("|| (ignore) {bounced} because {msg}"); } e => Err(e)?, }, diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs @@ -162,7 +162,7 @@ fn run(config: Option<PathBuf>) { Network::Regtest => "regtest", _ => unreachable!(), }; - info!("Running on {} chain", chain_name); + info!("Running on {chain_name} chain"); // TODO Check wire wallet own config PAYTO address let rpc_watcher = auto_rpc_common(state.btc_config.clone()); diff --git a/btc-wire/src/segwit.rs b/btc-wire/src/segwit.rs @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ use bech32::Hrp; -use common::{rand::rngs::ThreadRng, rand_slice}; +use common::{rand::rngs::ThreadRng, rand_slice, taler_common::api_common::EddsaPublicKey}; use std::cmp::Ordering; /// TODO use segwit v1 to only use a single address @@ -69,7 +69,9 @@ pub enum DecodeSegWitErr { } /// Decode a 32B key into from adresses -pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], DecodeSegWitErr> { +pub fn decode_segwit_msg( + segwit_addrs: &[impl AsRef<str>], +) -> Result<EddsaPublicKey, DecodeSegWitErr> { // Extract parts from every addresses let decoded: Vec<(bool, [u8; 4], [u8; 16])> = segwit_addrs .iter() @@ -113,7 +115,7 @@ pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], D for (is_first, _, half) in matches { key[*is_first as usize * 16..][..16].copy_from_slice(half); } - Ok(key) + Ok(EddsaPublicKey::from(key)) } Ordering::Greater => Err(DecodeSegWitErr::PrefixCollision), Ordering::Less => Err(DecodeSegWitErr::MissingSegWitAddress), @@ -139,7 +141,7 @@ pub fn rand_addresses(hrp: Hrp, key: &[u8; 32]) -> Vec<String> { mod test { use common::{ rand::{prelude::SliceRandom, rngs::ThreadRng}, - rand_slice, + taler_common::types::base32::Base32, }; use crate::segwit::{decode_segwit_msg, encode_segwit_key, rand_addresses}; @@ -148,7 +150,7 @@ mod test { fn test_shuffle() { let mut rng = ThreadRng::default(); for _ in 0..1000 { - let key = rand_slice(); + let key = Base32::rand(); let mut addresses = encode_segwit_key(bech32::hrp::TB, &key); addresses.shuffle(&mut rng); let decoded = @@ -161,7 +163,7 @@ mod test { #[test] fn test_shuffle_many() { for _ in 0..1000 { - let key = rand_slice(); + let key = Base32::rand(); let addresses = rand_addresses(bech32::hrp::TB, &key); let decoded = decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>()) diff --git a/common/src/metadata.rs b/common/src/metadata.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 @@ -16,6 +16,7 @@ use std::fmt::Debug; +use taler_common::api_common::{EddsaPublicKey, ShortHashCode}; use url::Url; #[derive(Debug, Clone, thiserror::Error)] @@ -37,7 +38,7 @@ pub enum EncodeErr { /// Encoded metadata for outgoing transaction #[derive(Debug, Clone, PartialEq, Eq)] pub enum OutMetadata { - Debit { wtid: [u8; 32], url: Url }, + Debit { wtid: ShortHashCode, url: Url }, Bounce { bounced: [u8; 32] }, } @@ -55,7 +56,7 @@ impl OutMetadata { scheme => return Err(EncodeErr::UnsupportedScheme(scheme.to_string())), }; buffer.push(scheme_id); - buffer.extend_from_slice(wtid); + buffer.extend_from_slice(wtid.as_slice()); let parts = format!("{}{}", url.domain().unwrap_or(""), url.path()); let packed = uri_pack::pack_uri(&parts).unwrap(); buffer.extend_from_slice(&packed); @@ -105,7 +106,7 @@ impl OutMetadata { /// Encoded metadata for incoming transaction #[derive(Debug, Clone, PartialEq, Eq)] pub enum InMetadata { - Credit { reserve_pub: [u8; 32] }, + Credit { reserve_pub: EddsaPublicKey }, } impl InMetadata { @@ -114,7 +115,7 @@ impl InMetadata { match self { InMetadata::Credit { reserve_pub } => { buffer.push(0); - buffer.extend_from_slice(reserve_pub); + buffer.extend_from_slice(reserve_pub.as_slice()); } } buffer @@ -141,6 +142,7 @@ impl InMetadata { #[cfg(test)] mod test { + use taler_common::api_common::{EddsaPublicKey, ShortHashCode}; use url::Url; use crate::{ @@ -152,7 +154,7 @@ mod test { fn decode_encode_credit() { for _ in 0..4 { let metadata = InMetadata::Credit { - reserve_pub: rand_slice(), + reserve_pub: EddsaPublicKey::rand(), }; let encoded = metadata.encode(); let decoded = InMetadata::decode(&encoded).unwrap(); @@ -169,7 +171,7 @@ mod test { "http://git.taler.net/depolymerization.git/", ]; for url in urls { - let wtid = rand_slice(); + let wtid = ShortHashCode::rand(); let url = Url::parse(url).unwrap(); let metadata = OutMetadata::Debit { wtid, url }; let encoded = metadata.encode().unwrap(); @@ -183,7 +185,7 @@ mod test { let url = "https+wtf://git.taler.net"; let url = Url::parse(url).unwrap(); let metadata = OutMetadata::Debit { - wtid: rand_slice(), + wtid: ShortHashCode::rand(), url, }; let encoded = metadata.encode(); diff --git a/common/src/sql.rs b/common/src/sql.rs @@ -19,7 +19,7 @@ use std::str::FromStr; use postgres::Row; use taler_common::{ api_common::SafeU64, - types::{amount::Amount, payto::PaytoURI}, + types::{amount::Amount, base32::Base32, payto::PaytoURI}, }; use url::Url; @@ -56,6 +56,18 @@ pub fn sql_array<const N: usize>(row: &Row, idx: usize) -> [u8; N] { }) } +/// Base32 from sql +pub fn sql_base_32<const N: usize>(row: &Row, idx: usize) -> Base32<N> { + let slice: &[u8] = row.get(idx); + slice.try_into().or_fail(|_| { + format!( + "Database invariant: expected a base32 byte array of {}B for {}B", + N, + slice.len() + ) + }) +} + /// Safe safe u64 from sql pub fn sql_safe_u64(row: &Row, idx: usize) -> SafeU64 { let id: i64 = row.get(idx); diff --git a/eth-wire/src/lib.rs b/eth-wire/src/lib.rs @@ -26,7 +26,10 @@ use common::{ log::{OrFail, fail}, metadata::{InMetadata, OutMetadata}, postgres, - taler_common::types::{amount::Amount, payto::PaytoURI}, + taler_common::{ + api_common::{EddsaPublicKey, ShortHashCode}, + types::{amount::Amount, payto::PaytoURI}, + }, url::Url, }; use ethereum_types::{Address, H160, H256, U64, U256}; @@ -47,7 +50,7 @@ pub trait RpcExtended: RpcClient { from: Address, to: Address, value: U256, - reserve_pub: [u8; 32], + reserve_pub: EddsaPublicKey, ) -> rpc::Result<H256> { let metadata = InMetadata::Credit { reserve_pub }; self.send_transaction(&rpc::TransactionRequest { @@ -66,7 +69,7 @@ pub trait RpcExtended: RpcClient { from: Address, to: Address, value: U256, - wtid: [u8; 32], + wtid: ShortHashCode, url: Url, ) -> rpc::Result<H256> { let metadata = OutMetadata::Debit { wtid, url }; diff --git a/eth-wire/src/loops/worker.rs b/eth-wire/src/loops/worker.rs @@ -20,9 +20,12 @@ use common::{ metadata::{InMetadata, OutMetadata}, postgres::{Client, fallible_iterator::FallibleIterator}, reconnect::AutoReconnectDb, - sql::{sql_array, sql_url}, + sql::{sql_array, sql_base_32, sql_url}, status::{BounceStatus, DebitStatus}, - taler_common::types::{base32::Base32, timestamp::Timestamp}, + taler_common::{ + api_common::ShortHashCode, + types::{timestamp::Timestamp}, + }, }; use eth_wire::{ ListSinceSync, RpcExtended, SyncState, SyncTransaction, @@ -244,8 +247,7 @@ fn sync_chain_removed( for (key, id, addr) in blocking_credit { write!( &mut buf, - "\n\tcredit {} in {} from {}", - Base32::from(key), + "\n\tcredit {key} in {} from {}", hex::encode(id), hex::encode(addr) ) @@ -283,9 +285,7 @@ fn sync_chain_incoming_confirmed( ])?; if nb > 0 { info!( - "<< {} {} in {} from {}", - amount, - Base32::from(reserve_pub), + "<< {amount} {reserve_pub} in {} from {}", hex::encode(tx.hash), hex::encode(credit_addr), ); @@ -338,9 +338,7 @@ fn sync_chain_outgoing(tx: &SyncTransaction, db: &mut Client, state: &WireState) match DebitStatus::try_from(status as u8).unwrap() { DebitStatus::Requested => { warn!( - ">> (recovered) {} {} in {} to {}", - amount, - Base32::from(wtid), + ">> (recovered) {amount} {wtid} in {} to {}", hex::encode(tx.hash), hex::encode(credit_addr) ); @@ -357,9 +355,7 @@ fn sync_chain_outgoing(tx: &SyncTransaction, db: &mut Client, state: &WireState) )?; if nb > 0 { warn!( - ">> (onchain) {} {} in {} to {}", - amount, - Base32::from(wtid), + ">> (onchain) {amount} {wtid} in {} to {}", hex::encode(tx.hash), hex::encode(credit_addr) ); @@ -434,11 +430,11 @@ fn debit(db: &mut Client, rpc: &mut Rpc, state: &WireState) -> LoopResult<bool> if let Some(row) = &row { let id: i64 = row.get(0); let amount = sql_eth_amount(row, 1, state.currency); - let wtid: [u8; 32] = sql_array(row, 3); + let wtid: ShortHashCode = sql_base_32(row, 3); let addr = sql_addr(row, 4); let url = sql_url(row, 5); let now = Timestamp::now(); - let tx_id = rpc.debit(state.address, addr, amount, wtid, url)?; + let tx_id = rpc.debit(state.address, addr, amount, wtid.clone(), url)?; fail_point("(injected) fail debit", 0.3)?; db.execute( "UPDATE tx_out SET status=$1, txid=$2, sent=$3 WHERE id=$4", @@ -451,9 +447,7 @@ fn debit(db: &mut Client, rpc: &mut Rpc, state: &WireState) -> LoopResult<bool> )?; let amount = eth_to_taler(&amount, state.currency); info!( - ">> {} {} in {} to {}", - amount, - Base32::from(wtid), + ">> {amount} {wtid} in {} to {}", hex::encode(tx_id), hex::encode(addr) ); @@ -487,9 +481,8 @@ fn bump(db: &mut Client, rpc: &mut Rpc, state: &WireState) -> LoopResult<bool> { "UPDATE tx_out SET sent=$1 WHERE id=$2 RETURNING wtid", &[&now.as_sql_micros(), &id], )?; - let wtid: &[u8] = row.get(0); - let wtid: [u8; 32] = wtid.try_into().unwrap(); - info!(">> (bump) {} in {}", Base32::from(wtid), hex::encode(txid)); + let wtid: ShortHashCode = sql_base_32(&row, 0); + info!(">> (bump) {wtid} in {}", hex::encode(txid)); } Ok(row.is_some()) } else { diff --git a/instrumentation/src/btc.rs b/instrumentation/src/btc.rs @@ -30,7 +30,7 @@ use btc_wire::{ rpc_utils::{self, segwit_min_amount}, taler_utils::{btc_payto_url, btc_to_taler}, }; -use common::{currency::CurrencyBtc, metadata::OutMetadata, postgres::NoTls, rand_slice}; +use common::{currency::CurrencyBtc, metadata::OutMetadata, postgres::NoTls, taler_common::{api_common::{EddsaPublicKey, ShortHashCode}, types::base32::Base32}}; use indicatif::ProgressBar; use tempfile::TempDir; @@ -125,7 +125,7 @@ pub fn online_test(config: Option<&Path>, base_url: &str) { let taler_test_amount = btc_to_taler(&test_amount.to_signed().unwrap(), state.currency); println!("Send transaction"); - let reserve_pub_key = rand_slice(); + let reserve_pub_key = Base32::rand(); let credit_id = client_rpc .send_segwit_key(&wire_addr, &test_amount, &reserve_pub_key) .unwrap(); @@ -195,7 +195,7 @@ pub fn online_test(config: Option<&Path>, base_url: &str) { )); println!("Get back some money"); - let wtid = rand_slice(); + let wtid = Base32::rand(); transfer( base_url, &wtid, @@ -423,16 +423,16 @@ impl BtcCtx { /* ----- Transaction ------ */ - pub fn credit(&mut self, amount: Amount, metadata: [u8; 32]) { + pub fn credit(&mut self, amount: Amount, metadata: &EddsaPublicKey) { self.client_rpc - .send_segwit_key(&self.wire_addr, &amount, &metadata) + .send_segwit_key(&self.wire_addr, &amount, metadata) .unwrap(); } - pub fn debit(&mut self, amount: Amount, metadata: [u8; 32]) { + pub fn debit(&mut self, amount: Amount, metadata: &ShortHashCode) { transfer( &self.ctx.gateway_url, - &metadata, + metadata, &self.state.base_url, btc_payto_url(&self.client_addr), &btc_to_taler(&amount.to_signed().unwrap(), self.state.currency), @@ -514,12 +514,12 @@ impl BtcCtx { /* ----- Wire Gateway ----- */ - pub fn expect_credits(&self, txs: &[([u8; 32], Amount)]) { + pub fn expect_credits(&self, txs: &[(EddsaPublicKey, Amount)]) { let txs: Vec<_> = txs .iter() .map(|(metadata, amount)| { ( - *metadata, + metadata.clone(), btc_to_taler(&amount.to_signed().unwrap(), self.state.currency), ) }) @@ -527,12 +527,12 @@ impl BtcCtx { self.ctx.expect_credits(&txs) } - pub fn expect_debits(&self, txs: &[([u8; 32], Amount)]) { + pub fn expect_debits(&self, txs: &[(ShortHashCode, Amount)]) { let txs: Vec<_> = txs .iter() .map(|(metadata, amount)| { ( - *metadata, + metadata.clone(), btc_to_taler(&amount.to_signed().unwrap(), self.state.currency), ) }) @@ -552,9 +552,9 @@ pub fn wire(ctx: TestCtx) { let mut balance = ctx.wire_balance(); let mut txs = Vec::new(); for n in 10..100 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(n * 1000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); txs.push((metadata, amount)); balance += amount; ctx.next_block(); @@ -569,10 +569,10 @@ pub fn wire(ctx: TestCtx) { let mut balance = ctx.client_balance(); let mut txs = Vec::new(); for n in 10..100 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(n * 100); balance += amount; - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); txs.push((metadata, amount)); } ctx.next_block(); @@ -603,14 +603,14 @@ pub fn lifetime(ctx: TestCtx) { retry(|| ctx.wire_running() && ctx.gateway_running()); // Consume wire lifetime for _ in 0..=ctx.taler_conf.wire_lifetime().unwrap() + 2 { - ctx.credit(segwit_min_amount(), rand_slice()); + ctx.credit(segwit_min_amount(), &Base32::rand()); ctx.next_block(); std::thread::sleep(Duration::from_millis(200)); } retry(|| !ctx.wire_running()); // Consume gateway lifetime for _ in 0..=ctx.taler_conf.http_lifetime().unwrap() { - ctx.debit(segwit_min_amount(), rand_slice()); + ctx.debit(segwit_min_amount(), &Base32::rand()); ctx.next_block(); } // End down @@ -627,9 +627,9 @@ pub fn reconnect(ctx: TestCtx) { ctx.step("With DB"); { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(42000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); ctx.next_block(); ctx.next_conf(); @@ -640,9 +640,9 @@ pub fn reconnect(ctx: TestCtx) { { ctx.stop_db(); ctx.malformed_credit(&Amount::from_sat(24000)); - let metadata = rand_slice(); + let metadata =Base32::rand(); let amount = Amount::from_sat(40000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); ctx.stop_node(); ctx.expect_gateway_down(); @@ -652,9 +652,9 @@ pub fn reconnect(ctx: TestCtx) { { ctx.resume_db(); ctx.resume_node(&[]); - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(2000); - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); debits.push((metadata, amount)); ctx.next_block(); sleep(Duration::from_secs(3)); @@ -688,9 +688,9 @@ pub fn stress(ctx: TestCtx) { { let mut balance = ctx.wire_balance(); for n in 10..30 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(n * 1000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); balance += amount; ctx.next_block(); @@ -704,10 +704,10 @@ pub fn stress(ctx: TestCtx) { { let mut balance = ctx.client_balance(); for n in 10..30 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = Amount::from_sat(n * 100); balance += amount; - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); debits.push((metadata, amount)); } ctx.next_block(); @@ -747,14 +747,14 @@ pub fn conflict(tctx: TestCtx) { { // Perform credit let amount = Amount::from_sat(4200000); - ctx.credit(amount, rand_slice()); + ctx.credit(amount, &Base32::rand()); ctx.next_conf(); ctx.expect_wire_balance(amount, true); let client = ctx.client_balance(); let wire = ctx.wire_balance(); // Perform debit - ctx.debit(Amount::from_sat(400000), rand_slice()); + ctx.debit(Amount::from_sat(400000), &Base32::rand()); retry(|| ctx.wire_balance() < wire); // Abandon pending transaction @@ -764,7 +764,7 @@ pub fn conflict(tctx: TestCtx) { ctx.expect_wire_balance(wire, false); // Generate conflict - ctx.debit(Amount::from_sat(500000), rand_slice()); + ctx.debit(Amount::from_sat(500000), &Base32::rand()); retry(|| ctx.wire_balance() < wire); // Resend conflicting transaction @@ -777,7 +777,7 @@ pub fn conflict(tctx: TestCtx) { ctx.step("Setup"); drop(ctx); let mut ctx = BtcCtx::setup(&tctx, "taler_btc.conf", false); - ctx.credit(Amount::from_sat(3000000), rand_slice()); + ctx.credit(Amount::from_sat(3000000), &Base32::rand()); ctx.next_block(); ctx.step("Conflict bounce"); @@ -797,7 +797,7 @@ pub fn conflict(tctx: TestCtx) { // Generate conflict let amount = Amount::from_sat(50000); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); retry(|| ctx.wire_balance() < (wire + bounce_amount)); // Resend conflicting transaction @@ -821,7 +821,7 @@ pub fn reorg(ctx: TestCtx) { // Perform credits let before = ctx.wire_balance(); for n in 10..21 { - ctx.credit(Amount::from_sat(n * 10000), rand_slice()); + ctx.credit(Amount::from_sat(n * 10000), &Base32::rand()); ctx.next_block(); } let after = ctx.wire_balance(); @@ -848,7 +848,7 @@ pub fn reorg(ctx: TestCtx) { let mut after = ctx.client_balance(); for n in 10..21 { let amount = Amount::from_sat(n * 100); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); after += amount; } ctx.next_block(); @@ -917,7 +917,7 @@ pub fn hell(ctx: TestCtx) { ctx.restart_node(&["-minrelaytxfee=0.001"]); ctx.abandon_client(); let amount = Amount::from_sat(54000); - ctx.credit(amount, rand_slice()); + ctx.credit(amount, &Base32::rand()); ctx.expect_wire_balance(amount, true); // Check btc-wire suspend operation @@ -930,7 +930,7 @@ pub fn hell(ctx: TestCtx) { step(&ctx, "Handle reorg conflicting incoming credit", |ctx| { let amount = Amount::from_sat(420000); - ctx.credit(amount, rand_slice()); + ctx.credit(amount, &Base32::rand()); ctx.next_conf(); ctx.expect_wire_balance(amount, true); }); @@ -956,7 +956,7 @@ pub fn analysis(ctx: TestCtx) { // Perform credit let before = ctx.wire_balance(); - ctx.credit(Amount::from_sat(42000), rand_slice()); + ctx.credit(Amount::from_sat(42000), &Base32::rand()); ctx.next_conf(); let after = ctx.wire_balance(); @@ -977,7 +977,7 @@ pub fn analysis(ctx: TestCtx) { // Perform credit let before = ctx.wire_balance(); - ctx.credit(Amount::from_sat(42000), rand_slice()); + ctx.credit(Amount::from_sat(42000), &Base32::rand()); ctx.next_conf(); // Perform fork and check btc-wire learned from previous attack @@ -995,7 +995,7 @@ pub fn bumpfee(tctx: TestCtx) { // Perform credits to allow wire to perform debits latter for n in 10..13 { - ctx.credit(Amount::from_sat(n * 100000), rand_slice()); + ctx.credit(Amount::from_sat(n * 100000), &Base32::rand()); ctx.next_block(); } ctx.next_conf(); @@ -1006,7 +1006,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut client = ctx.client_balance(); let wire = ctx.wire_balance(); let amount = Amount::from_sat(40000); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); retry(|| ctx.wire_balance() < wire); // Bump min relay fee making the previous debit stuck @@ -1026,7 +1026,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut client = ctx.client_balance(); let wire = ctx.wire_balance(); let amount = Amount::from_sat(40000); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); retry(|| ctx.wire_balance() < wire); // Bump min relay fee and fork making the previous debit stuck and problematic @@ -1043,7 +1043,7 @@ pub fn bumpfee(tctx: TestCtx) { // Perform credits to allow wire to perform debits latter for n in 10..61 { - ctx.credit(Amount::from_sat(n * 100000), rand_slice()); + ctx.credit(Amount::from_sat(n * 100000), &Base32::rand()); ctx.next_block(); } ctx.next_conf(); @@ -1060,7 +1060,7 @@ pub fn bumpfee(tctx: TestCtx) { for n in 10..31 { let amount = Amount::from_sat(n * 10000); total_amount += amount; - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); } retry(|| ctx.wire_balance() < wire - total_amount); @@ -1079,7 +1079,7 @@ pub fn maxfee(ctx: TestCtx) { // Perform credits to allow wire to perform debits latter for n in 10..31 { - ctx.credit(Amount::from_sat(n * 100000), rand_slice()); + ctx.credit(Amount::from_sat(n * 100000), &Base32::rand()); ctx.next_block(); } ctx.next_conf(); @@ -1097,7 +1097,7 @@ pub fn maxfee(ctx: TestCtx) { for n in 10..31 { let amount = Amount::from_sat(n * 10000); total_amount += amount; - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); } ctx.mine(2); diff --git a/instrumentation/src/eth.rs b/instrumentation/src/eth.rs @@ -21,7 +21,14 @@ use std::{ time::Duration, }; -use common::{metadata::OutMetadata, postgres::NoTls, rand_slice}; +use common::{ + metadata::OutMetadata, + postgres::NoTls, + taler_common::{ + api_common::{EddsaPublicKey, ShortHashCode}, + types::base32::Base32, + }, +}; use eth_wire::{ RpcExtended, SyncState, WireState, rpc::{Rpc, RpcClient, TransactionRequest, hex::Hex}, @@ -93,9 +100,14 @@ pub fn online_test(config: Option<&Path>, base_url: &str) { }; println!("Send transaction"); - let reserve_pub_key = rand_slice(); + let reserve_pub_key = Base32::rand(); let credit_id = rpc - .credit(client_addr, state.address, test_amount, reserve_pub_key) + .credit( + client_addr, + state.address, + test_amount, + reserve_pub_key.clone(), + ) .unwrap(); let zero_id = rpc .send_transaction(&TransactionRequest { @@ -177,7 +189,7 @@ pub fn online_test(config: Option<&Path>, base_url: &str) { )); println!("Get back some money"); - let wtid = rand_slice(); + let wtid = Base32::rand(); transfer( base_url, &wtid, @@ -506,16 +518,21 @@ impl EthCtx { /* ----- Transaction ------ */ - pub fn credit(&mut self, amount: U256, metadata: [u8; 32]) { + pub fn credit(&mut self, amount: U256, reserve_pub: &EddsaPublicKey) { self.rpc - .credit(self.client_addr, self.wire_addr, amount, metadata) + .credit( + self.client_addr, + self.wire_addr, + amount, + reserve_pub.clone(), + ) .unwrap(); } - pub fn debit(&mut self, amount: U256, metadata: [u8; 32]) { + pub fn debit(&mut self, amount: U256, wtid: &ShortHashCode) { transfer( &self.ctx.gateway_url, - &metadata, + wtid, &self.state.base_url, eth_payto_url(&self.client_addr), &eth_to_taler(&amount, self.state.currency), @@ -619,18 +636,18 @@ impl EthCtx { /* ----- Wire Gateway ----- */ - pub fn expect_credits(&self, txs: &[([u8; 32], U256)]) { + pub fn expect_credits(&self, txs: &[(EddsaPublicKey, U256)]) { let txs: Vec<_> = txs .iter() - .map(|(metadata, amount)| (*metadata, eth_to_taler(amount, self.state.currency))) + .map(|(metadata, amount)| (metadata.clone(), eth_to_taler(amount, self.state.currency))) .collect(); self.ctx.expect_credits(&txs) } - pub fn expect_debits(&self, txs: &[([u8; 32], U256)]) { + pub fn expect_debits(&self, txs: &[(ShortHashCode, U256)]) { let txs: Vec<_> = txs .iter() - .map(|(metadata, amount)| (*metadata, eth_to_taler(amount, self.state.currency))) + .map(|(metadata, amount)| (metadata.clone(), eth_to_taler(amount, self.state.currency))) .collect(); self.ctx.expect_debits(&self.state.base_url, &txs) } @@ -647,10 +664,10 @@ pub fn wire(ctx: TestCtx) { let mut balance = ctx.wire_balance(); let mut txs = Vec::new(); for n in 10..100 { - let metadata = rand_slice(); + let reserve_pub = Base32::rand(); let amount = ctx.amount(n * 1000); - ctx.credit(amount, metadata); - txs.push((metadata, amount)); + ctx.credit(amount, &reserve_pub); + txs.push((reserve_pub, amount)); balance += amount; } ctx.next_conf(); @@ -663,10 +680,10 @@ pub fn wire(ctx: TestCtx) { let mut balance = ctx.client_balance(); let mut txs = Vec::new(); for n in 10..100 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(n * 100); balance += amount; - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); txs.push((metadata, amount)); } ctx.next_block(); @@ -696,11 +713,11 @@ pub fn lifetime(ctx: TestCtx) { retry(|| ctx.wire_running() && ctx.gateway_running()); // Consume lifetime for n in 0..=ctx.taler_conf.wire_lifetime().unwrap() { - ctx.credit(ctx.amount(n * 1000), rand_slice()); + ctx.credit(ctx.amount(n * 1000), &Base32::rand()); ctx.next_block(); } for n in 0..=ctx.taler_conf.http_lifetime().unwrap() { - ctx.debit(ctx.amount(n * 1000), rand_slice()); + ctx.debit(ctx.amount(n * 1000), &Base32::rand()); } // End down retry(|| !ctx.wire_running() && !ctx.gateway_running()); @@ -716,9 +733,9 @@ pub fn reconnect(ctx: TestCtx) { ctx.step("With DB"); { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(42000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); ctx.next_block(); ctx.next_conf(); @@ -729,9 +746,9 @@ pub fn reconnect(ctx: TestCtx) { { ctx.stop_db(); ctx.malformed_credit(ctx.amount(24000)); - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(4000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); ctx.stop_node(); ctx.expect_error(); @@ -741,9 +758,9 @@ pub fn reconnect(ctx: TestCtx) { { ctx.resume_db(); ctx.resume_node(&[]); - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(2000); - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); debits.push((metadata, amount)); ctx.next_block(); sleep(Duration::from_secs(3)); @@ -781,9 +798,9 @@ pub fn stress(ctx: TestCtx) { { let mut balance = ctx.wire_balance(); for n in 10..30 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(n * 1000); - ctx.credit(amount, metadata); + ctx.credit(amount, &metadata); credits.push((metadata, amount)); balance += amount; } @@ -796,10 +813,10 @@ pub fn stress(ctx: TestCtx) { { let mut balance = ctx.client_balance(); for n in 10..30 { - let metadata = rand_slice(); + let metadata = Base32::rand(); let amount = ctx.amount(n * 100); balance += amount; - ctx.debit(amount, metadata); + ctx.debit(amount, &metadata); debits.push((metadata, amount)); } ctx.next_block(); @@ -842,7 +859,7 @@ pub fn reorg(ctx: TestCtx) { // Perform credits let before = ctx.wire_balance(); for n in 10..21 { - ctx.credit(ctx.amount(n * 10000), rand_slice()); + ctx.credit(ctx.amount(n * 10000), &Base32::rand()); } ctx.next_conf(); let after = ctx.wire_balance(); @@ -869,7 +886,7 @@ pub fn reorg(ctx: TestCtx) { let mut after = ctx.client_balance(); for n in 10..21 { let amount = ctx.amount(n * 100); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); after += amount; } ctx.next_block(); @@ -938,7 +955,7 @@ pub fn hell(ctx: TestCtx) { ctx.restart_node(&["--miner.gasprice", "1000"]); ctx.abandon(); let amount = ctx.amount(54000); - ctx.credit(amount, rand_slice()); + ctx.credit(amount, &Base32::rand()); ctx.expect_wire_balance(amount, true); // Check eth-wire suspend operation @@ -951,7 +968,7 @@ pub fn hell(ctx: TestCtx) { step(&ctx, "Handle reorg conflicting incoming credit", |ctx| { let amount = ctx.amount(420000); - ctx.credit(amount, rand_slice()); + ctx.credit(amount, &Base32::rand()); ctx.next_conf(); ctx.expect_wire_balance(amount, true); }); @@ -976,7 +993,7 @@ pub fn analysis(ctx: TestCtx) { // Perform credit let before = ctx.wire_balance(); - ctx.credit(ctx.amount(42000), rand_slice()); + ctx.credit(ctx.amount(42000), &Base32::rand()); ctx.next_conf(); let after = ctx.wire_balance(); @@ -996,7 +1013,7 @@ pub fn analysis(ctx: TestCtx) { // Perform credit let before = ctx.wire_balance(); - ctx.credit(ctx.amount(42000), rand_slice()); + ctx.credit(ctx.amount(42000), &Base32::rand()); ctx.next_conf(); // Perform fork and check eth-wire learned from previous attack @@ -1013,7 +1030,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut ctx = EthCtx::setup(&tctx, "taler_eth_bump.conf", false); // Perform credits to allow wire to perform debits latter - ctx.credit(ctx.amount(90000000), rand_slice()); + ctx.credit(ctx.amount(90000000), &Base32::rand()); ctx.next_conf(); ctx.step("Bump fee"); @@ -1022,7 +1039,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut client = ctx.client_balance(); let wire = ctx.wire_balance(); let amount = ctx.amount(40000); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); retry(|| ctx.wire_balance_pending() < wire); // Bump min relay fee making the previous debit stuck @@ -1042,7 +1059,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut client = ctx.client_balance(); let wire = ctx.wire_balance(); let amount = ctx.amount(40000); - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); retry(|| ctx.wire_balance_pending() < wire); // Bump min relay fee and fork making the previous debit stuck and problematic @@ -1059,7 +1076,7 @@ pub fn bumpfee(tctx: TestCtx) { let mut ctx = EthCtx::setup(&tctx, "taler_eth_bump.conf", true); // Perform credit to allow wire to perform debits latter - ctx.credit(ctx.amount(9000000), rand_slice()); + ctx.credit(ctx.amount(9000000), &Base32::rand()); ctx.next_conf(); ctx.step("Bump fee stress"); @@ -1074,7 +1091,7 @@ pub fn bumpfee(tctx: TestCtx) { for n in 10..31 { let amount = ctx.amount(n * 10000); total_amount += amount; - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); } retry(|| ctx.wire_balance_pending() < wire - total_amount); @@ -1092,7 +1109,7 @@ pub fn maxfee(ctx: TestCtx) { let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false); // Perform credit to allow wire to perform debits latter - ctx.credit(ctx.amount(9000000), rand_slice()); + ctx.credit(ctx.amount(9000000), &Base32::rand()); ctx.next_conf(); let client = ctx.client_balance(); @@ -1108,7 +1125,7 @@ pub fn maxfee(ctx: TestCtx) { for n in 10..31 { let amount = ctx.amount(n * 10000); total_amount += amount; - ctx.debit(amount, rand_slice()); + ctx.debit(amount, &Base32::rand()); } sleep(Duration::from_secs(3)); diff --git a/instrumentation/src/utils.rs b/instrumentation/src/utils.rs @@ -30,6 +30,7 @@ use std::{ use common::{ config::TalerConfig, taler_common::{ + api_common::{EddsaPublicKey, ShortHashCode}, api_wire::{IncomingBankTransaction, IncomingHistory, OutgoingHistory, TransferRequest}, types::{amount::Amount, base32::Base32, payto::PaytoURI}, }, @@ -45,9 +46,9 @@ pub fn print_now(disp: impl Display) { } #[must_use] -pub fn check_incoming(base_url: &str, txs: &[([u8; 32], Amount)]) -> bool { +pub fn check_incoming(base_url: &str, txs: &[(EddsaPublicKey, Amount)]) -> bool { let mut res = ureq::get(&format!("{}history/incoming", base_url)) - .query("delta", &format!("-{}", txs.len())) + .query("delta", format!("-{}", txs.len())) .call() .unwrap(); if txs.is_empty() { @@ -61,15 +62,15 @@ pub fn check_incoming(base_url: &str, txs: &[([u8; 32], Amount)]) -> bool { history.incoming_transactions.len() == txs.len() && txs.iter().all(|(reserve_pub_key, taler_amount)| { history.incoming_transactions.iter().any(|h| { - matches!( - h, - IncomingBankTransaction::Reserve { - reserve_pub, - amount, - .. - } if reserve_pub == &Base32::from(*reserve_pub_key) && amount == taler_amount - ) - }) + matches!( + h, + IncomingBankTransaction::Reserve { + reserve_pub, + amount, + .. + } if reserve_pub == reserve_pub_key && amount == taler_amount + ) + }) }) } } @@ -135,9 +136,9 @@ pub fn transfer( } #[must_use] -pub fn check_outgoing(base_url: &str, url: &Url, txs: &[([u8; 32], Amount)]) -> bool { +pub fn check_outgoing(base_url: &str, url: &Url, txs: &[(ShortHashCode, Amount)]) -> bool { let mut res = ureq::get(&format!("{}history/outgoing", base_url)) - .query("delta", &format!("-{}", txs.len())) + .query("delta", format!("-{}", txs.len())) .call() .unwrap(); if txs.is_empty() { @@ -150,11 +151,10 @@ pub fn check_outgoing(base_url: &str, url: &Url, txs: &[([u8; 32], Amount)]) -> history.outgoing_transactions.len() == txs.len() && txs.iter().all(|(wtid, amount)| { - history.outgoing_transactions.iter().any(|h| { - h.wtid == Base32::from(*wtid) - && &h.exchange_base_url == url - && &h.amount == amount - }) + history + .outgoing_transactions + .iter() + .any(|h| h.wtid == *wtid && &h.exchange_base_url == url && &h.amount == amount) }) } } @@ -420,11 +420,11 @@ impl TalerCtx { /* ----- Wire Gateway -----*/ - pub fn expect_credits(&self, txs: &[([u8; 32], Amount)]) { + pub fn expect_credits(&self, txs: &[(EddsaPublicKey, Amount)]) { retry(|| check_incoming(&self.gateway_url, txs)) } - pub fn expect_debits(&self, base_url: &Url, txs: &[([u8; 32], Amount)]) { + pub fn expect_debits(&self, base_url: &Url, txs: &[(ShortHashCode, Amount)]) { retry(|| check_outgoing(&self.gateway_url, base_url, txs)) }