commit f02af95ef2579c30090491eb8e0f04a0a0b50d9d parent a54ddfe59882553ea52753c79d6c7c6a85ce7f37 Author: Antoine A <> Date: Fri, 28 Mar 2025 13:05:03 +0100 Update rust and edition Diffstat:
28 files changed, 363 insertions(+), 340 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "wire-gateway", "btc-wire", @@ -9,6 +9,13 @@ members = [ "instrumentation", ] +[workspace.package] +edition = "2024" +authors = ["Taler Systems SA <deb@taler.net>"] +homepage = "https://taler.net/" +repository = "https://git.taler.net/depolymerization.git" +license-file = "LICENSE" + [profile.dev] debug = true diff --git a/btc-wire/Cargo.toml b/btc-wire/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "btc-wire" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" -rust-version = "1.72.1" +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [features] # Enable random failures diff --git a/btc-wire/benches/metadata.rs b/btc-wire/benches/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 @@ -15,7 +15,7 @@ */ use btc_wire::segwit::{decode_segwit_msg, encode_segwit_key, rand_addresses}; use common::rand_slice; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; fn criterion_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("SegWit addresses"); diff --git a/btc-wire/src/bin/segwit-demo.rs b/btc-wire/src/bin/segwit-demo.rs @@ -66,7 +66,9 @@ pub fn main() { println!("\nⅢ - Send to many"); let minimum = rpc_utils::segwit_min_amount().to_btc(); println!("Send a single bitcoin transaction with the three addresses as recipient as follow:"); - println!("\nIn bitcoincore wallet use 'Add Recipient' button to add two additional recipient and copy adresses and amounts"); + println!( + "\nIn bitcoincore wallet use 'Add Recipient' button to add two additional recipient and copy adresses and amounts" + ); let first = Address::from_str(&first).unwrap().assume_checked(); let second = Address::from_str(&second).unwrap().assume_checked(); for (address, amount) in [(&address, btc), (&first, minimum), (&second, minimum)] { diff --git a/btc-wire/src/btc_config.rs b/btc-wire/src/btc_config.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 @@ -22,7 +22,7 @@ use std::{ use bitcoin::Network; use common::{ currency::CurrencyBtc, - log::{fail, OrFail}, + log::{OrFail, fail}, }; use crate::{ diff --git a/btc-wire/src/lib.rs b/btc-wire/src/lib.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,12 +16,12 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; -use bitcoin::{hashes::hex::FromHex, Address, Amount, Network, Txid}; +use bitcoin::{Address, Amount, Network, Txid, hashes::hex::FromHex}; use btc_config::BitcoinConfig; use common::{ config::TalerConfig, currency::{Currency, CurrencyBtc}, - log::{fail, OrFail}, + log::{OrFail, fail}, postgres, taler_common::types::amount::Amount as TalerAmount, url::Url, diff --git a/btc-wire/src/loops/worker.rs b/btc-wire/src/loops/worker.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 @@ -15,17 +15,17 @@ */ use std::{collections::HashMap, fmt::Write, time::SystemTime}; -use bitcoin::{hashes::Hash, Amount as BtcAmount, BlockHash, Txid}; +use bitcoin::{Amount as BtcAmount, BlockHash, Txid, hashes::Hash}; use btc_wire::{ + GetOpReturnErr, GetSegwitErr, rpc::{self, AutoRpcWallet, Category, ErrorCode, Rpc, Transaction}, rpc_utils::sender_address, taler_utils::{btc_payto_url, btc_to_taler}, - GetOpReturnErr, GetSegwitErr, }; use common::{ log::{ - log::{error, info, warn}, OrFail, + log::{error, info, warn}, }, metadata::OutMetadata, postgres, @@ -34,15 +34,15 @@ use common::{ status::{BounceStatus, DebitStatus}, taler_common::types::{base32::Base32, timestamp::Timestamp}, }; -use postgres::{fallible_iterator::FallibleIterator, Client}; +use postgres::{Client, fallible_iterator::FallibleIterator}; use crate::{ + WireState, fail_point::fail_point, sql::{sql_addr, sql_btc_amount, sql_txid}, - WireState, }; -use super::{analysis::analysis, LoopError, LoopResult}; +use super::{LoopError, LoopResult, analysis::analysis}; /// Synchronize local db with blockchain and perform transactions pub fn worker(mut rpc: AutoRpcWallet, mut db: AutoReconnectDb, mut state: WireState) { diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs @@ -1,174 +1,176 @@ -/* - This file is part of TALER - Copyright (C) 2022 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 - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -use bitcoin::{hashes::Hash, Network}; -use btc_wire::{ - btc_config::{BitcoinConfig, WIRE_WALLET_NAME}, - load_taler_config, - rpc::{self, auto_rpc_common, auto_rpc_wallet, ErrorCode, Rpc}, - WireState, -}; -use clap::Parser; -use common::{ - log::{log::info, OrFail}, - named_spawn, password, - postgres::NoTls, - reconnect::auto_reconnect_db, -}; -use loops::LoopResult; -use std::path::PathBuf; - -use crate::loops::{watcher::watcher, worker::worker}; - -mod fail_point; -mod loops; -mod sql; - -/// Taler wire for bitcoincore -#[derive(clap::Parser, Debug)] -struct Args { - /// Override default configuration file path - #[clap(global = true, short, long)] - config: Option<PathBuf>, - #[clap(subcommand)] - init: Option<Init>, -} - -#[derive(clap::Subcommand, Debug)] -enum Init { - /// Initialize database schema and state - Initdb, - /// Generate bitcoin wallet and initialize state - Initwallet, -} - -/// TODO support external signer https://github.com/bitcoin/bitcoin/blob/master/doc/external-signer.md - -fn main() { - common::log::init(); - let args = Args::parse(); - - match args.init { - Some(cmd) => init(args.config, cmd).or_fail(|e| format!("{}", e)), - None => run(args.config), - } -} - -fn init(config: Option<PathBuf>, init: Init) -> LoopResult<()> { - // Parse taler config - let (taler_config, path, currency) = load_taler_config(config.as_deref()); - // Connect to database - let mut db = taler_config.db_config().connect(NoTls)?; - // Parse bitcoin config - let btc_conf = - BitcoinConfig::load(path, currency).or_fail(|e| format!("bitcoin config: {}", e)); - // Connect to bitcoin node - let mut rpc = Rpc::common(&btc_conf).or_fail(|e| format!("rpc connect: {}", e)); - match init { - Init::Initdb => { - let mut tx = db.transaction()?; - // Load schema - tx.batch_execute(include_str!("../../db/btc.sql"))?; - // Init status to true - tx - .execute( - "INSERT INTO state (name, value) VALUES ('status', $1) ON CONFLICT (name) DO NOTHING", - &[&[1u8].as_slice()], - )?; - // Init last_hash if not already set - let genesis_hash = rpc.get_genesis()?; - tx - .execute( - "INSERT INTO state (name, value) VALUES ('last_hash', $1) ON CONFLICT (name) DO NOTHING", - &[&genesis_hash.as_byte_array().as_slice()], - )?; - tx.commit()?; - println!("Database initialised"); - } - Init::Initwallet => { - // Create wallet - let passwd = password(); - let created = match rpc.create_wallet(WIRE_WALLET_NAME, &passwd) { - Err(rpc::Error::RPC { - code: ErrorCode::RpcWalletError, - .. - }) => false, - Err(e) => panic!("{}", e), - Ok(_) => true, - }; - - rpc.load_wallet(WIRE_WALLET_NAME).ok(); - - // Load previous address - // TODO Use address label instead of the database ? - let prev_addr = db.query_opt("SELECT value FROM state WHERE name = 'addr'", &[])?; - let addr = if let Some(row) = prev_addr { - String::from_utf8(row.get(0)).unwrap() - } else { - // Or generate a new one - let new = Rpc::wallet(&btc_conf, WIRE_WALLET_NAME) - .or_fail(|e| format!("rpc connect: {}", e)) - .gen_addr()?; - db.execute( - "INSERT INTO state (name, value) VALUES ('addr', $1)", - &[&new.to_string().as_bytes()], - )?; - new.to_string() - }; - - if created { - println!("Created new wallet"); - } else { - println!("Found already existing wallet") - } - println!("You must backup the generated key file and your chosen password, more info there: https://github.com/bitcoin/bitcoin/blob/master/doc/managing-wallets.md#14-backing-up-the-wallet"); - println!("Public address is {}", &addr); - println!("Add the following line into taler.conf:"); - println!("[depolymerizer-bitcoin]"); - println!("PAYTO = payto://bitcoin/{}", addr); - } - } - Ok(()) -} - -fn run(config: Option<PathBuf>) { - let state = WireState::load_taler_config(config.as_deref()); - - #[cfg(feature = "fail")] - if state.btc_config.network == Network::Regtest { - common::log::log::warn!("Running with random failures"); - } else { - common::log::log::error!("Running with random failures is unsuitable for production"); - std::process::exit(1); - } - let chain_name = match state.btc_config.network { - Network::Bitcoin => "main", - Network::Testnet => "test", - Network::Signet => "signet", - Network::Regtest => "regtest", - _ => unreachable!(), - }; - info!("Running on {} chain", chain_name); - // TODO Check wire wallet own config PAYTO address - - let rpc_watcher = auto_rpc_common(state.btc_config.clone()); - let rpc_worker = auto_rpc_wallet(state.btc_config.clone(), WIRE_WALLET_NAME); - - let db_watcher = auto_reconnect_db(state.db_config.clone()); - let db_worker = auto_reconnect_db(state.db_config.clone()); - named_spawn("watcher", move || watcher(rpc_watcher, db_watcher)); - worker(rpc_worker, db_worker, state); - info!("btc-wire stopped"); -} +/* + This file is part of TALER + 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +use bitcoin::{Network, hashes::Hash}; +use btc_wire::{ + WireState, + btc_config::{BitcoinConfig, WIRE_WALLET_NAME}, + load_taler_config, + rpc::{self, ErrorCode, Rpc, auto_rpc_common, auto_rpc_wallet}, +}; +use clap::Parser; +use common::{ + log::{OrFail, log::info}, + named_spawn, password, + postgres::NoTls, + reconnect::auto_reconnect_db, +}; +use loops::LoopResult; +use std::path::PathBuf; + +use crate::loops::{watcher::watcher, worker::worker}; + +mod fail_point; +mod loops; +mod sql; + +/// Taler wire for bitcoincore +#[derive(clap::Parser, Debug)] +struct Args { + /// Override default configuration file path + #[clap(global = true, short, long)] + config: Option<PathBuf>, + #[clap(subcommand)] + init: Option<Init>, +} + +#[derive(clap::Subcommand, Debug)] +enum Init { + /// Initialize database schema and state + Initdb, + /// Generate bitcoin wallet and initialize state + Initwallet, +} + +/// TODO support external signer https://github.com/bitcoin/bitcoin/blob/master/doc/external-signer.md + +fn main() { + common::log::init(); + let args = Args::parse(); + + match args.init { + Some(cmd) => init(args.config, cmd).or_fail(|e| format!("{}", e)), + None => run(args.config), + } +} + +fn init(config: Option<PathBuf>, init: Init) -> LoopResult<()> { + // Parse taler config + let (taler_config, path, currency) = load_taler_config(config.as_deref()); + // Connect to database + let mut db = taler_config.db_config().connect(NoTls)?; + // Parse bitcoin config + let btc_conf = + BitcoinConfig::load(path, currency).or_fail(|e| format!("bitcoin config: {}", e)); + // Connect to bitcoin node + let mut rpc = Rpc::common(&btc_conf).or_fail(|e| format!("rpc connect: {}", e)); + match init { + Init::Initdb => { + let mut tx = db.transaction()?; + // Load schema + tx.batch_execute(include_str!("../../db/btc.sql"))?; + // Init status to true + tx + .execute( + "INSERT INTO state (name, value) VALUES ('status', $1) ON CONFLICT (name) DO NOTHING", + &[&[1u8].as_slice()], + )?; + // Init last_hash if not already set + let genesis_hash = rpc.get_genesis()?; + tx + .execute( + "INSERT INTO state (name, value) VALUES ('last_hash', $1) ON CONFLICT (name) DO NOTHING", + &[&genesis_hash.as_byte_array().as_slice()], + )?; + tx.commit()?; + println!("Database initialised"); + } + Init::Initwallet => { + // Create wallet + let passwd = password(); + let created = match rpc.create_wallet(WIRE_WALLET_NAME, &passwd) { + Err(rpc::Error::RPC { + code: ErrorCode::RpcWalletError, + .. + }) => false, + Err(e) => panic!("{}", e), + Ok(_) => true, + }; + + rpc.load_wallet(WIRE_WALLET_NAME).ok(); + + // Load previous address + // TODO Use address label instead of the database ? + let prev_addr = db.query_opt("SELECT value FROM state WHERE name = 'addr'", &[])?; + let addr = if let Some(row) = prev_addr { + String::from_utf8(row.get(0)).unwrap() + } else { + // Or generate a new one + let new = Rpc::wallet(&btc_conf, WIRE_WALLET_NAME) + .or_fail(|e| format!("rpc connect: {}", e)) + .gen_addr()?; + db.execute( + "INSERT INTO state (name, value) VALUES ('addr', $1)", + &[&new.to_string().as_bytes()], + )?; + new.to_string() + }; + + if created { + println!("Created new wallet"); + } else { + println!("Found already existing wallet") + } + println!( + "You must backup the generated key file and your chosen password, more info there: https://github.com/bitcoin/bitcoin/blob/master/doc/managing-wallets.md#14-backing-up-the-wallet" + ); + println!("Public address is {}", &addr); + println!("Add the following line into taler.conf:"); + println!("[depolymerizer-bitcoin]"); + println!("PAYTO = payto://bitcoin/{}", addr); + } + } + Ok(()) +} + +fn run(config: Option<PathBuf>) { + let state = WireState::load_taler_config(config.as_deref()); + + #[cfg(feature = "fail")] + if state.btc_config.network == Network::Regtest { + common::log::log::warn!("Running with random failures"); + } else { + common::log::log::error!("Running with random failures is unsuitable for production"); + std::process::exit(1); + } + let chain_name = match state.btc_config.network { + Network::Bitcoin => "main", + Network::Testnet => "test", + Network::Signet => "signet", + Network::Regtest => "regtest", + _ => unreachable!(), + }; + info!("Running on {} chain", chain_name); + // TODO Check wire wallet own config PAYTO address + + let rpc_watcher = auto_rpc_common(state.btc_config.clone()); + let rpc_worker = auto_rpc_wallet(state.btc_config.clone(), WIRE_WALLET_NAME); + + let db_watcher = auto_reconnect_db(state.db_config.clone()); + let db_worker = auto_reconnect_db(state.db_config.clone()); + named_spawn("watcher", move || watcher(rpc_watcher, db_watcher)); + worker(rpc_worker, db_worker, state); + info!("btc-wire stopped"); +} diff --git a/btc-wire/src/rpc.rs b/btc-wire/src/rpc.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 @@ -25,10 +25,10 @@ //! //! bitcoincore RPC documentation: <https://bitcoincore.org/en/doc/23.0.0/> -use bitcoin::{address::NetworkUnchecked, Address, Amount, BlockHash, SignedAmount, Txid}; +use bitcoin::{Address, Amount, BlockHash, SignedAmount, Txid, address::NetworkUnchecked}; use common::{log::log::error, password, reconnect::AutoReconnect}; use data_encoding::BASE64; -use serde_json::{json, Value}; +use serde_json::{Value, json}; use std::{ fmt::Debug, io::{self, BufRead, BufReader, Write}, diff --git a/btc-wire/src/sql.rs b/btc-wire/src/sql.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,7 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -use bitcoin::{hashes::Hash, Address, Amount as BtcAmount, Txid}; +use bitcoin::{Address, Amount as BtcAmount, Txid, hashes::Hash}; use common::currency::CurrencyBtc; use common::log::OrFail; use common::postgres::Row; diff --git a/common/Cargo.toml b/common/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "common" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" -rust-version = "1.72.1" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [dependencies] # Serialization framework diff --git a/common/src/config.rs b/common/src/config.rs @@ -22,16 +22,16 @@ use std::{ process::Command, str::FromStr, }; -use taler_api::{auth::AuthMethod, Serve}; +use taler_api::{Serve, auth::AuthMethod}; use taler_common::{ - config::{parser::ConfigErr, Config, Section}, + config::{Config, Section, parser::ConfigErr}, types::payto::PaytoURI, }; use url::Url; use crate::{ currency::Currency, - log::{fail, OrFail}, + log::{OrFail, fail}, }; // Depolymerizer taler config diff --git a/common/src/lib.rs b/common/src/lib.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,7 +16,7 @@ use std::{process::exit, thread::JoinHandle}; use ::log::error; -use rand::{rngs::OsRng, RngCore}; +use rand::{RngCore, rngs::OsRng}; use zeroize::Zeroizing; pub use postgres; diff --git a/eth-wire/Cargo.toml b/eth-wire/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "eth-wire" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" -rust-version = "1.72.1" +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [features] # Enable random failures diff --git a/eth-wire/src/lib.rs b/eth-wire/src/lib.rs @@ -23,14 +23,14 @@ use std::{ use common::{ config::TalerConfig, currency::{Currency, CurrencyEth}, - log::{fail, OrFail}, + log::{OrFail, fail}, metadata::{InMetadata, OutMetadata}, postgres, taler_common::types::{amount::Amount, payto::PaytoURI}, url::Url, }; -use ethereum_types::{Address, H160, H256, U256, U64}; -use rpc::{hex::Hex, Rpc, RpcClient, RpcStream, Transaction}; +use ethereum_types::{Address, H160, H256, U64, U256}; +use rpc::{Rpc, RpcClient, RpcStream, Transaction, hex::Hex}; use rpc_utils::default_data_dir; use serde::de::DeserializeOwned; use taler_util::{eth_payto_addr, taler_to_eth}; diff --git a/eth-wire/src/loops/worker.rs b/eth-wire/src/loops/worker.rs @@ -18,27 +18,27 @@ use std::fmt::Write; use common::{ log::log::{error, info, warn}, metadata::{InMetadata, OutMetadata}, - postgres::{fallible_iterator::FallibleIterator, Client}, + postgres::{Client, fallible_iterator::FallibleIterator}, reconnect::AutoReconnectDb, sql::{sql_array, sql_url}, status::{BounceStatus, DebitStatus}, taler_common::types::{base32::Base32, timestamp::Timestamp}, }; use eth_wire::{ + ListSinceSync, RpcExtended, SyncState, SyncTransaction, rpc::{self, AutoRpcWallet, Rpc, RpcClient, Transaction, TransactionRequest}, taler_util::{eth_payto_url, eth_to_taler}, - ListSinceSync, RpcExtended, SyncState, SyncTransaction, }; use ethereum_types::{Address, H256, U256}; use crate::{ + WireState, fail_point::fail_point, loops::LoopError, sql::{sql_addr, sql_eth_amount, sql_hash}, - WireState, }; -use super::{analysis::analysis, LoopResult}; +use super::{LoopResult, analysis::analysis}; pub fn worker(mut rpc: AutoRpcWallet, mut db: AutoReconnectDb, mut state: WireState) { let mut lifetime = state.lifetime; diff --git a/eth-wire/src/main.rs b/eth-wire/src/main.rs @@ -18,18 +18,17 @@ use std::path::PathBuf; use clap::Parser; use common::{ - log::{log::info, OrFail}, + log::{OrFail, log::info}, 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, + SyncState, WireState, load_taler_config, + rpc::{Rpc, RpcClient, auto_rpc_common, auto_rpc_wallet}, }; use ethereum_types::H160; -use loops::{watcher::watcher, worker::worker, LoopResult}; +use loops::{LoopResult, watcher::watcher, worker::worker}; mod fail_point; mod loops; @@ -132,7 +131,9 @@ fn init(config: Option<PathBuf>, init: Init) -> LoopResult<()> { }; let addr = hex::encode(addr.as_bytes()); - println!("You must backup the generated key file and your chosen password, more info there: https://geth.ethereum.org/docs/install-and-build/backup-restore"); + println!( + "You must backup the generated key file and your chosen password, more info there: https://geth.ethereum.org/docs/install-and-build/backup-restore" + ); println!("Public address is {}", &addr); println!("Add the following line into taler.conf:"); println!("[depolymerizer-ethereum]"); diff --git a/eth-wire/src/rpc.rs b/eth-wire/src/rpc.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 @@ -20,7 +20,7 @@ //! make our code more compatible with future deprecation use common::{log::log::error, password, reconnect::AutoReconnect, url::Url}; -use ethereum_types::{Address, H160, H256, U256, U64}; +use ethereum_types::{Address, H160, H256, U64, U256}; use serde::de::DeserializeOwned; use std::{ fmt::Debug, @@ -300,7 +300,7 @@ impl<N: Debug + DeserializeOwned> RpcClient for RpcStream<'_, N> { self.buff.push(n.result); } NotificationOrResponse::Response(response) => { - return self.rpc.handle_response(response) + return self.rpc.handle_response(response); } } } @@ -517,8 +517,8 @@ pub mod hex { }; use serde::{ - de::{Error, Unexpected, Visitor}, Deserialize, Deserializer, Serialize, Serializer, + de::{Error, Unexpected, Visitor}, }; /// Raw bytes wrapper diff --git a/instrumentation/Cargo.toml b/instrumentation/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "instrumentation" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" -rust-version = "1.72.1" +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [dependencies] # Cli args parser diff --git a/instrumentation/src/btc.rs b/instrumentation/src/btc.rs @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022-2024 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 @@ -22,21 +22,21 @@ use std::{ time::Duration, }; -use bitcoin::{hashes::Hash, Address, Amount, BlockHash, Network, SignedAmount, Txid}; +use bitcoin::{Address, Amount, BlockHash, Network, SignedAmount, Txid, hashes::Hash}; use btc_wire::{ + WireState, btc_config::BitcoinConfig, rpc::{self, Category, ErrorCode, Rpc}, rpc_utils::{self, segwit_min_amount}, taler_utils::{btc_payto_url, btc_to_taler}, - WireState, }; use common::{currency::CurrencyBtc, metadata::OutMetadata, postgres::NoTls, rand_slice}; use indicatif::ProgressBar; use tempfile::TempDir; use crate::utils::{ - check_incoming, check_outgoing, cmd_redirect, cmd_redirect_ok, print_now, retry, retry_opt, - transfer, unused_port, ChildGuard, TalerCtx, TestCtx, + ChildGuard, TalerCtx, TestCtx, check_incoming, check_outgoing, cmd_redirect, cmd_redirect_ok, + print_now, retry, retry_opt, transfer, unused_port, }; pub const CLIENT: &str = "client"; diff --git a/instrumentation/src/eth.rs b/instrumentation/src/eth.rs @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022-2024 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 @@ -23,15 +23,15 @@ use std::{ use common::{metadata::OutMetadata, postgres::NoTls, rand_slice}; use eth_wire::{ - rpc::{hex::Hex, Rpc, RpcClient, TransactionRequest}, - taler_util::{eth_payto_url, eth_to_taler, TRUNC}, RpcExtended, SyncState, WireState, + rpc::{Rpc, RpcClient, TransactionRequest, hex::Hex}, + taler_util::{TRUNC, eth_payto_url, eth_to_taler}, }; use ethereum_types::{H160, H256, U256}; use crate::utils::{ - check_incoming, check_outgoing, cmd_out, cmd_redirect, cmd_redirect_ok, print_now, retry, - retry_opt, transfer, unused_port, ChildGuard, TalerCtx, TestCtx, + ChildGuard, TalerCtx, TestCtx, check_incoming, check_outgoing, cmd_out, cmd_redirect, + cmd_redirect_ok, print_now, retry, retry_opt, transfer, unused_port, }; fn wait_for_pending(rpc: &mut Rpc) { diff --git a/instrumentation/src/gateway.rs b/instrumentation/src/gateway.rs @@ -22,7 +22,7 @@ use common::taler_common::{ types::{ amount::Amount, base32::Base32, - payto::{payto, PaytoURI}, + payto::{PaytoURI, payto}, }, }; use libdeflater::{CompressionLvl, Compressor}; @@ -30,7 +30,7 @@ use ureq::Response; use crate::{ btc::BtcCtx, - utils::{cmd_out, cmd_redirect_ok, gateway_error, TestCtx}, + utils::{TestCtx, cmd_out, cmd_redirect_ok, gateway_error}, }; fn client_transfer(gateway_url: &str, payto_url: &PaytoURI, amount: &str) -> String { diff --git a/instrumentation/src/main.rs b/instrumentation/src/main.rs @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022-2024 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 @@ -29,7 +29,7 @@ use owo_colors::OwoColorize; use thread_local_panic_hook::set_hook; use utils::TestDb; -use crate::utils::{try_cmd_redirect, TestCtx}; +use crate::utils::{TestCtx, try_cmd_redirect}; mod btc; mod eth; @@ -92,7 +92,9 @@ pub fn main() { // Generate password let pwd: String = (0..30).map(|_| fastrand::alphanumeric()).collect(); - std::env::set_var("PASSWORD", pwd); + unsafe { + std::env::set_var("PASSWORD", pwd); + } // Run tests let m = MultiProgress::new(); diff --git a/uri-pack/Cargo.toml b/uri-pack/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "uri-pack" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [dependencies] # Error macros diff --git a/uri-pack/benches/pack.rs b/uri-pack/benches/pack.rs @@ -1,80 +1,80 @@ -/* - This file is part of TALER - Copyright (C) 2022 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 - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; -use uri_pack::{pack_uri, unpack_uri}; - -/// Ascii char that can be packed into 5 bits -pub(crate) const PACKED: [u8; 30] = [ - b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', - b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', b'z', b'.', b'/', b'-', b'%', -]; - -fn rand_compat(size: usize) -> String { - String::from_utf8( - std::iter::repeat_with(|| fastrand::u8(b'!'..=b'~')) - .take(size) - .collect(), - ) - .unwrap() -} - -fn rand_simple(size: usize) -> String { - String::from_utf8( - std::iter::repeat_with(|| PACKED[fastrand::usize(..PACKED.len())]) - .take(size) - .collect(), - ) - .unwrap() -} - -fn criterion_benchmark(c: &mut Criterion) { - let mut group = c.benchmark_group("Uri"); - for size in [50, 500, 4048].iter() { - group.throughput(Throughput::Bytes(*size as u64)); - group.bench_with_input(BenchmarkId::new("pack rand", size), size, |b, &size| { - b.iter_batched( - || rand_compat(size), - |uri| pack_uri(&uri).unwrap(), - criterion::BatchSize::SmallInput, - ) - }); - group.bench_with_input(BenchmarkId::new("unpack rand", size), size, |b, &size| { - b.iter_batched( - || pack_uri(&rand_compat(size)).unwrap(), - |packed| unpack_uri(&packed), - criterion::BatchSize::SmallInput, - ) - }); - group.bench_with_input(BenchmarkId::new("pack simple", size), size, |b, &size| { - b.iter_batched( - || rand_simple(size), - |uri| pack_uri(&uri).unwrap(), - criterion::BatchSize::SmallInput, - ) - }); - group.bench_with_input(BenchmarkId::new("unpack simple", size), size, |b, &size| { - b.iter_batched( - || pack_uri(&rand_simple(size)).unwrap(), - |packed| unpack_uri(&packed), - criterion::BatchSize::SmallInput, - ) - }); - } - group.finish(); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); +/* + This file is part of TALER + 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; +use uri_pack::{pack_uri, unpack_uri}; + +/// Ascii char that can be packed into 5 bits +pub(crate) const PACKED: [u8; 30] = [ + b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', + b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', b'z', b'.', b'/', b'-', b'%', +]; + +fn rand_compat(size: usize) -> String { + String::from_utf8( + std::iter::repeat_with(|| fastrand::u8(b'!'..=b'~')) + .take(size) + .collect(), + ) + .unwrap() +} + +fn rand_simple(size: usize) -> String { + String::from_utf8( + std::iter::repeat_with(|| PACKED[fastrand::usize(..PACKED.len())]) + .take(size) + .collect(), + ) + .unwrap() +} + +fn criterion_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("Uri"); + for size in [50, 500, 4048].iter() { + group.throughput(Throughput::Bytes(*size as u64)); + group.bench_with_input(BenchmarkId::new("pack rand", size), size, |b, &size| { + b.iter_batched( + || rand_compat(size), + |uri| pack_uri(&uri).unwrap(), + criterion::BatchSize::SmallInput, + ) + }); + group.bench_with_input(BenchmarkId::new("unpack rand", size), size, |b, &size| { + b.iter_batched( + || pack_uri(&rand_compat(size)).unwrap(), + |packed| unpack_uri(&packed), + criterion::BatchSize::SmallInput, + ) + }); + group.bench_with_input(BenchmarkId::new("pack simple", size), size, |b, &size| { + b.iter_batched( + || rand_simple(size), + |uri| pack_uri(&uri).unwrap(), + criterion::BatchSize::SmallInput, + ) + }); + group.bench_with_input(BenchmarkId::new("unpack simple", size), size, |b, &size| { + b.iter_batched( + || pack_uri(&rand_simple(size)).unwrap(), + |packed| unpack_uri(&packed), + criterion::BatchSize::SmallInput, + ) + }); + } + group.finish(); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/uri-pack/src/lib.rs b/uri-pack/src/lib.rs @@ -200,7 +200,7 @@ mod test { use serde_json::Value; - use crate::{pack_ascii, pack_uri, supported_ascii, unpack_ascii, unpack_uri, EXTENDED}; + use crate::{EXTENDED, pack_ascii, pack_uri, supported_ascii, unpack_ascii, unpack_uri}; /// Ascii char that can be packed into 5 bits const PACKED: [u8; 30] = [ diff --git a/wire-gateway/Cargo.toml b/wire-gateway/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "wire-gateway" version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-or-later" -rust-version = "1.72.1" +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license-file.workspace = true [dependencies] axum.workspace = true diff --git a/wire-gateway/src/main.rs b/wire-gateway/src/main.rs @@ -24,28 +24,28 @@ use common::{ config::WireGatewayCfg, currency::Currency, log::{ - log::{error, info}, OrFail, + log::{error, info}, }, }; use sqlx::Row; -use sqlx::{postgres::PgListener, PgPool, QueryBuilder}; +use sqlx::{PgPool, QueryBuilder, postgres::PgListener}; use std::{ path::PathBuf, str::FromStr as _, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, time::Duration, }; use taler_api::{ api::{ - wire::{self, WireGateway}, TalerApi, TalerRouter, + wire::{self, WireGateway}, }, - db::{page, BindHelper, TypeHelper}, - error::{failure, failure_status, ApiResult}, + db::{BindHelper, TypeHelper, page}, + error::{ApiResult, failure, failure_status}, }; use taler_common::{ api_params::{History, Page},