gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-depolymerization] branch master updated (638b738 -> ec1d604)


From: gnunet
Subject: [taler-depolymerization] branch master updated (638b738 -> ec1d604)
Date: Thu, 24 Feb 2022 13:59:51 +0100

This is an automated email from the git hooks/post-receive script.

antoine pushed a change to branch master
in repository depolymerization.

    from 638b738  Better instrumentation test
     new 87a6363  btc-wire: reconnect on auto wallet rpc refresh
     new ec1d604  instrumentation: readme and better code

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Cargo.lock                  |  24 ++---
 btc-wire/src/lib.rs         |  38 ++++++-
 btc-wire/src/main.rs        |  44 ++------
 btc-wire/src/rpc.rs         |   3 +
 instrumentation/README.md   |  20 ++++
 instrumentation/src/btc.rs  | 246 ++++++++++++++++++++++++++++++++++++++++++
 instrumentation/src/main.rs | 254 +-------------------------------------------
 7 files changed, 331 insertions(+), 298 deletions(-)
 create mode 100644 instrumentation/README.md
 create mode 100644 instrumentation/src/btc.rs

diff --git a/Cargo.lock b/Cargo.lock
index 26d0e9d..aafb32d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -124,7 +124,7 @@ dependencies = [
  "base64",
  "bech32",
  "bitcoin",
- "clap 3.1.1",
+ "clap 3.1.2",
  "common",
  "criterion",
  "hex",
@@ -206,9 +206,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "3.1.1"
+version = "3.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "6d76c22c9b9b215eeb8d016ad3a90417bd13cb24cf8142756e6472445876cab7"
+checksum = "5177fac1ab67102d8989464efd043c6ff44191b1557ec1ddd489b4f7e1447e77"
 dependencies = [
  "atty",
  "bitflags",
@@ -223,9 +223,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "3.1.0"
+version = "3.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5fd1122e63869df2cb309f449da1ad54a7c6dfeb7c7e6ccd8e0825d9eb93bb72"
+checksum = "01d42c94ce7c2252681b5fed4d3627cc807b13dfc033246bd05d5b252399000e"
 dependencies = [
  "heck",
  "proc-macro-error",
@@ -497,7 +497,7 @@ dependencies = [
 name = "eth-wire"
 version = "0.1.0"
 dependencies = [
- "clap 3.1.1",
+ "clap 3.1.2",
  "common",
  "ethereum-types",
  "hex",
@@ -703,9 +703,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
+checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
 dependencies = [
  "cfg-if",
  "libc",
@@ -890,7 +890,7 @@ version = "0.1.0"
 dependencies = [
  "bitcoin",
  "btc-wire",
- "clap 3.1.1",
+ "clap 3.1.2",
  "common",
  "eth-wire",
  "ureq",
@@ -1546,9 +1546,9 @@ dependencies = [
 
 [[package]]
 name = "semver"
-version = "1.0.5"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7"
+checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
 
 [[package]]
 name = "serde"
@@ -2169,7 +2169,7 @@ name = "wire-gateway"
 version = "0.1.0"
 dependencies = [
  "bitcoin",
- "clap 3.1.1",
+ "clap 3.1.2",
  "common",
  "deadpool-postgres",
  "ethereum-types",
diff --git a/btc-wire/src/lib.rs b/btc-wire/src/lib.rs
index 554f4ea..0dd1b14 100644
--- a/btc-wire/src/lib.rs
+++ b/btc-wire/src/lib.rs
@@ -14,14 +14,16 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 use std::str::FromStr;
+use std::sync::atomic::AtomicU16;
 
 use bitcoin::{hashes::hex::FromHex, Address, Amount, Network, Txid};
+use common::api_common::Amount as TalerAmount;
 use common::config::BtcConfig;
+use config::BitcoinConfig;
 use rpc::{Category, Rpc, Transaction};
-use rpc_utils::{segwit_min_amount, sender_address};
+use rpc_utils::{default_data_dir, segwit_min_amount, sender_address};
 use segwit::{decode_segwit_msg, encode_segwit_key};
 use taler_utils::taler_to_btc;
-use common::api_common::Amount as TalerAmount;
 
 pub mod config;
 pub mod metadata;
@@ -140,11 +142,41 @@ impl Rpc {
 }
 
 const DEFAULT_BOUNCE_FEE: &'static str = "BTC:0.00001";
+const DEFAULT_CONFIRMATION: u16 = 6;
 
-pub fn config_bounce_fee(config: &BtcConfig) -> Amount {
+fn config_bounce_fee(config: &BtcConfig) -> Amount {
     let config = config.bounce_fee.as_deref().unwrap_or(DEFAULT_BOUNCE_FEE);
     TalerAmount::from_str(&config)
         .ok()
         .and_then(|a| taler_to_btc(&a).ok())
         .expect("config value BOUNCE_FEE is no a valid bitcoin amount")
 }
+
+pub struct WireState {
+    pub confirmation: AtomicU16,
+    pub max_confirmation: u16,
+    pub config: BtcConfig,
+    pub btc_config: BitcoinConfig,
+    pub bounce_fee: Amount,
+}
+
+impl WireState {
+    pub fn from_taler_config(config: BtcConfig) -> Self {
+        let data_dir = config
+            .core
+            .data_dir
+            .as_ref()
+            .cloned()
+            .unwrap_or_else(default_data_dir);
+        let btc_config =
+            BitcoinConfig::load(&data_dir).expect("Failed to read bitcoin 
configuration file");
+        let init_confirmation = 
config.confirmation.unwrap_or(DEFAULT_CONFIRMATION);
+        Self {
+            confirmation: AtomicU16::new(init_confirmation),
+            max_confirmation: init_confirmation * 2,
+            bounce_fee: config_bounce_fee(&config),
+            config,
+            btc_config,
+        }
+    }
+}
diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs
index 2d78294..7bf28ad 100644
--- a/btc-wire/src/main.rs
+++ b/btc-wire/src/main.rs
@@ -13,22 +13,22 @@
   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::{Amount as BtcAmount, Network};
+use bitcoin::Network;
 use btc_wire::{
     config::{BitcoinConfig, WIRE_WALLET_NAME},
-    config_bounce_fee,
     rpc::{self, auto_rpc_common, auto_rpc_wallet, ErrorCode, Rpc},
     rpc_utils::default_data_dir,
+    WireState,
 };
 use clap::StructOpt;
 use common::{
-    config::{load_btc_config, BtcConfig, Config, CoreConfig},
+    config::{load_btc_config, Config, CoreConfig},
     log::log::info,
     named_spawn, password,
     postgres::{Client, NoTls},
     reconnect::auto_reconnect_db,
 };
-use std::{path::PathBuf, sync::atomic::AtomicU16};
+use std::path::PathBuf;
 
 use crate::loops::{analysis::analysis, watcher::watcher, worker::worker};
 
@@ -36,14 +36,6 @@ mod fail_point;
 mod loops;
 mod sql;
 
-const DEFAULT_CONFIRMATION: u16 = 6;
-pub struct WireState {
-    confirmation: AtomicU16,
-    max_confirmation: u16,
-    config: BtcConfig,
-    bounce_fee: BtcAmount,
-}
-
 /// Taler wire for bitcoincore
 #[derive(clap::Parser, Debug)]
 struct Args {
@@ -168,22 +160,16 @@ fn init(config: Option<PathBuf>, init: Init) {
 
 fn run(config: Option<PathBuf>) {
     let config = load_btc_config(config.as_deref());
-    let data_dir = config
-        .core
-        .data_dir
-        .as_ref()
-        .cloned()
-        .unwrap_or_else(default_data_dir);
-    let btc_config = BitcoinConfig::load(&data_dir).unwrap();
+    let state: &'static _ = 
Box::leak(Box::new(WireState::from_taler_config(config)));
 
     #[cfg(feature = "fail")]
-    if btc_config.network == Network::Regtest {
+    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 btc_config.network {
+    let chain_name = match state.btc_config.network {
         Network::Bitcoin => "main",
         Network::Testnet => "test",
         Network::Signet => "signet",
@@ -191,19 +177,9 @@ fn run(config: Option<PathBuf>) {
     };
     info!("Running on {} chain", chain_name);
 
-    let init_confirmation = 
config.confirmation.unwrap_or(DEFAULT_CONFIRMATION);
-    let state: &'static WireState = Box::leak(Box::new(WireState {
-        confirmation: AtomicU16::new(init_confirmation),
-        max_confirmation: init_confirmation * 2,
-        bounce_fee: config_bounce_fee(&config),
-        config,
-    }));
-
-    let mut rpc = Rpc::common(&btc_config).unwrap();
-    rpc.load_wallet(WIRE_WALLET_NAME).ok();
-    let rpc_watcher = auto_rpc_common(btc_config.clone());
-    let rpc_analysis = auto_rpc_common(btc_config.clone());
-    let rpc_worker = auto_rpc_wallet(btc_config, WIRE_WALLET_NAME);
+    let rpc_watcher = auto_rpc_common(state.btc_config.clone());
+    let rpc_analysis = 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.config.core.db_url.clone());
     let db_analysis = auto_reconnect_db(state.config.core.db_url.clone());
diff --git a/btc-wire/src/rpc.rs b/btc-wire/src/rpc.rs
index a00b7fd..8834640 100644
--- a/btc-wire/src/rpc.rs
+++ b/btc-wire/src/rpc.rs
@@ -46,6 +46,9 @@ pub fn auto_rpc_wallet(config: BitcoinConfig, wallet: 
&'static str) -> AutoRpcWa
             let mut rpc = Rpc::wallet(config, wallet)
                 .map_err(|err| error!("connect RPC: {}", err))
                 .ok()?;
+            rpc.load_wallet(wallet)
+                .map_err(|err| error!("connect RPC: {}", err))
+                .ok()?;
             rpc.unlock_wallet(&password())
                 .map_err(|err| error!("connect RPC: {}", err))
                 .ok()?;
diff --git a/instrumentation/README.md b/instrumentation/README.md
new file mode 100644
index 0000000..772ebce
--- /dev/null
+++ b/instrumentation/README.md
@@ -0,0 +1,20 @@
+# Depolymerizer instrumentation test
+
+Unit tests running on a private development network are meant to test the good
+behavior in case of extreme situation but do not attest our capacity to handle
+real network behavior.
+
+## Install
+
+`cargo install --path instrumentation`
+
+## Run
+
+First, follow a normal setup for the adapter and then run `instrumentation`. 
The
+tested blockchain will be determined based on the taler configuration.
+
+## Temporary database
+
+If you do not want to use a persistent database for instrumentation tests, 
there
+is a [script](../script/tmp_db.sh) to generate a temporary database similar to
+unit tests.
diff --git a/instrumentation/src/btc.rs b/instrumentation/src/btc.rs
new file mode 100644
index 0000000..eaa1285
--- /dev/null
+++ b/instrumentation/src/btc.rs
@@ -0,0 +1,246 @@
+/*
+  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 std::{path::Path, time::Duration};
+
+use bitcoin::{Amount, BlockHash, Network, SignedAmount};
+use btc_wire::{
+    metadata::OutMetadata,
+    rpc::{self, Category, ErrorCode, Rpc, Transaction},
+    rpc_utils,
+    taler_utils::{btc_payto_url, btc_to_taler},
+    WireState,
+};
+use common::{
+    api_common::Base32,
+    api_wire::{IncomingBankTransaction, IncomingHistory, OutgoingHistory, 
TransferRequest},
+    config::load_btc_config,
+    rand_slice,
+};
+
+use crate::print_now;
+
+pub const CLIENT: &str = "client";
+pub const WIRE: &str = "wire";
+
+fn unsigned(amount: SignedAmount) -> Amount {
+    amount.abs().to_unsigned().unwrap()
+}
+
+fn wait_for_pending(since: &mut BlockHash, client_rpc: &mut Rpc, wire_rpc: 
&mut Rpc) {
+    print_now("Wait for pending transactions mining:");
+    'l: loop {
+        std::thread::sleep(Duration::from_secs(1)); // Wait for btc-wire to act
+        let sync = client_rpc.list_since_block(Some(&since), 1).unwrap();
+        let sync2 = wire_rpc.list_since_block(Some(&since), 1).unwrap();
+        *since = sync.lastblock;
+        for tx in sync
+            .transactions
+            .into_iter()
+            .chain(sync2.transactions.into_iter())
+        {
+            if tx.confirmations == 0 {
+                client_rpc.wait_for_new_block().unwrap();
+                print_now(".");
+                continue 'l;
+            }
+        }
+        break;
+    }
+    println!("");
+}
+
+pub fn btc_test(config: Option<&Path>, base_url: &str) {
+    let config = load_btc_config(config);
+    let state = WireState::from_taler_config(config);
+
+    if state.btc_config.network == Network::Bitcoin {
+        panic!("You should never run this test on a real bitcoin network");
+    }
+
+    let min_fund = Amount::from_sat(10_000);
+
+    let mut rpc = Rpc::common(&state.btc_config).unwrap();
+    // Load client
+    match rpc.load_wallet(CLIENT) {
+        Ok(_) => {}
+        Err(rpc::Error::RPC {
+            code: ErrorCode::RpcWalletNotFound,
+            ..
+        }) => {
+            rpc.create_wallet(CLIENT, "").unwrap();
+        }
+        Err(rpc::Error::RPC {
+            code: ErrorCode::RpcWalletError | 
ErrorCode::RpcWalletAlreadyLoaded,
+            ..
+        }) => {}
+        Err(e) => panic!("{}", e),
+    };
+    let mut client_rpc = Rpc::wallet(&state.btc_config, CLIENT).unwrap();
+    let client_addr = client_rpc.gen_addr().unwrap();
+    if client_rpc.get_balance().unwrap() < min_fund {
+        println!(
+            "Client need a minimum of {} BTC to run this test, send coins to 
this address: {}",
+            min_fund.as_btc(),
+            client_addr
+        );
+        print_now("Waiting for fund:");
+        while client_rpc.get_balance().unwrap() < min_fund {
+            client_rpc.wait_for_new_block().unwrap();
+            print_now(".");
+        }
+        println!("");
+    }
+    let mut since = client_rpc.list_since_block(None, 1).unwrap().lastblock;
+    // Load wire
+    let mut wire_rpc = Rpc::wallet(&state.btc_config, WIRE).unwrap();
+    let wire_addr = wire_rpc.gen_addr().unwrap();
+
+    wait_for_pending(&mut since, &mut client_rpc, &mut wire_rpc);
+
+    // Load balances
+    let client_balance = client_rpc.get_balance().unwrap();
+    let wire_balance = wire_rpc.get_balance().unwrap();
+    // Test amount
+    let test_amount = Amount::from_sat(2000);
+    let min_send_amount = rpc_utils::segwit_min_amount(); // To small to send 
back
+    let min_bounce_amount = min_send_amount + Amount::from_sat(999); // To 
small after bounce fee
+    let taler_test_amount = btc_to_taler(&test_amount.to_signed().unwrap());
+
+    println!("Send transaction");
+    let reserve_pub_key = rand_slice();
+    let deposit_id = client_rpc
+        .send_segwit_key(&wire_addr, &test_amount, &reserve_pub_key)
+        .unwrap();
+    let bounce_min_id = client_rpc
+        .send(&wire_addr, &min_bounce_amount, None, false)
+        .unwrap();
+    let send_min_id = client_rpc
+        .send(&wire_addr, &min_send_amount, None, false)
+        .unwrap();
+    let bounce_id = client_rpc
+        .send(&wire_addr, &test_amount, None, false)
+        .unwrap();
+    let client_sent_amount_cost =
+        test_amount + min_send_amount * 2 + min_bounce_amount + 
min_send_amount + test_amount;
+    let client_sent_fees_cost: Amount = [deposit_id, bounce_min_id, 
send_min_id, bounce_id]
+        .into_iter()
+        .map(|id| unsigned(client_rpc.get_tx(&id).unwrap().fee.unwrap()))
+        .reduce(|acc, i| acc + i)
+        .unwrap();
+    let new_balance = client_rpc.get_balance().unwrap();
+    assert_eq!(
+        client_balance - client_sent_amount_cost - client_sent_fees_cost,
+        new_balance
+    );
+
+    print_now("Wait for bounce:");
+    let bounce: Transaction = 'l: loop {
+        let sync = client_rpc.list_since_block(Some(&since), 1).unwrap();
+        for tx in sync.transactions {
+            if tx.category == Category::Receive {
+                let (tx, metadata) = 
client_rpc.get_tx_op_return(&tx.txid).unwrap();
+                let metadata = OutMetadata::decode(&metadata).unwrap();
+                match metadata {
+                    OutMetadata::Withdraw { .. } => {}
+                    OutMetadata::Bounce { bounced } => {
+                        if bounced == bounce_id {
+                            break 'l tx;
+                        } else if bounced == send_min_id {
+                            panic!("Bounced send min");
+                        } else if bounced == bounce_min_id {
+                            panic!("Bounced bounce min");
+                        }
+                    }
+                }
+            }
+        }
+        since = sync.lastblock;
+        rpc.wait_for_new_block().unwrap();
+        print_now(".");
+    };
+    println!("");
+    wait_for_pending(&mut since, &mut client_rpc, &mut wire_rpc);
+
+    println!("Check balance");
+    let new_client_balance = client_rpc.get_balance().unwrap();
+    let new_wire_balance = wire_rpc.get_balance().unwrap();
+    assert_eq!(
+        client_balance - client_sent_amount_cost - client_sent_fees_cost + 
unsigned(bounce.amount),
+        new_client_balance
+    );
+    assert_eq!(
+        wire_balance + test_amount + min_bounce_amount + min_send_amount + 
state.bounce_fee,
+        new_wire_balance
+    );
+
+    println!("Check history");
+    let history: IncomingHistory = ureq::get(&format!("{}/history/incoming", 
base_url))
+        .query("delta", "-5")
+        .call()
+        .unwrap()
+        .into_json()
+        .unwrap();
+    assert!(history
+        .incoming_transactions
+        .iter()
+        .find(|h| {
+            matches!(
+                h,
+                IncomingBankTransaction::IncomingReserveTransaction {
+                    reserve_pub,
+                    amount,
+                    ..
+                } if reserve_pub == &Base32::from(reserve_pub_key) && amount 
== &taler_test_amount
+            )
+        })
+        .is_some());
+
+    println!("Get back some money");
+    let wtid = rand_slice();
+    ureq::post(&format!("{}/transfer", base_url))
+        .send_json(TransferRequest {
+            request_uid: Base32::from(rand_slice()),
+            amount: taler_test_amount.clone(),
+            exchange_base_url: state.config.base_url.clone(),
+            wtid: Base32::from(wtid),
+            credit_account: btc_payto_url(&client_addr),
+        })
+        .unwrap();
+
+    wait_for_pending(&mut since, &mut client_rpc, &mut wire_rpc);
+
+    println!("Check balances");
+    let last_client_balance = client_rpc.get_balance().unwrap();
+    assert_eq!(new_client_balance + test_amount, last_client_balance);
+
+    println!("Check history");
+    let history: OutgoingHistory = ureq::get(&format!("{}/history/outgoing", 
base_url))
+        .query("delta", "-5")
+        .call()
+        .unwrap()
+        .into_json()
+        .unwrap();
+    assert!(history
+        .outgoing_transactions
+        .iter()
+        .find(|h| {
+            h.wtid == Base32::from(wtid)
+                && h.exchange_base_url == state.config.base_url
+                && h.amount == taler_test_amount
+        })
+        .is_some());
+}
diff --git a/instrumentation/src/main.rs b/instrumentation/src/main.rs
index 2b4943f..9c42a26 100644
--- a/instrumentation/src/main.rs
+++ b/instrumentation/src/main.rs
@@ -14,32 +14,13 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-use std::{fmt::Display, io::Write, path::PathBuf, time::Duration};
+use std::{fmt::Display, io::Write, path::PathBuf};
 
-use bitcoin::{Amount, Network, SignedAmount};
-use btc_wire::{
-    config::BitcoinConfig,
-    config_bounce_fee,
-    metadata::OutMetadata,
-    rpc::{self, Category, ErrorCode, Rpc},
-    rpc_utils::{self, default_data_dir},
-    taler_utils::{btc_payto_url, btc_to_taler},
-};
+use btc::btc_test;
 use clap::StructOpt;
-use common::{
-    api_common::Base32,
-    api_wire::{IncomingBankTransaction, IncomingHistory, OutgoingHistory, 
TransferRequest},
-    config::{load_btc_config, Config, GatewayConfig},
-    rand_slice,
-    url::Url,
-};
+use common::config::{Config, GatewayConfig};
 
-pub const CLIENT: &str = "client";
-pub const WIRE: &str = "wire";
-
-fn unsigned(amount: SignedAmount) -> Amount {
-    amount.abs().to_unsigned().unwrap()
-}
+mod btc;
 
 fn print_now(disp: impl Display) {
     print!("{}", disp);
@@ -61,232 +42,7 @@ pub fn main() {
     let base_url = format!("http://localhost:{}";, gateway_conf.port);
 
     match gateway_conf.core.currency.as_str() {
-        "BTC" => {
-            let config = load_btc_config(args.config.as_deref());
-            let data_dir = config
-                .core
-                .data_dir
-                .as_ref()
-                .cloned()
-                .unwrap_or_else(default_data_dir);
-            let btc_config = BitcoinConfig::load(&data_dir).unwrap();
-
-            if btc_config.network == Network::Bitcoin {
-                panic!("You should never run this test on a real bitcoin 
network");
-            }
-
-            let bounce_fee = config_bounce_fee(&config);
-            let min_fund = Amount::from_sat(10_000);
-
-            let mut rpc = Rpc::common(&btc_config).unwrap();
-            // Load client
-            match rpc.load_wallet(CLIENT) {
-                Ok(_) => {}
-                Err(rpc::Error::RPC {
-                    code: ErrorCode::RpcWalletNotFound,
-                    ..
-                }) => {
-                    rpc.create_wallet(CLIENT, "").unwrap();
-                }
-                Err(rpc::Error::RPC {
-                    code: ErrorCode::RpcWalletError | 
ErrorCode::RpcWalletAlreadyLoaded,
-                    ..
-                }) => {}
-                Err(e) => panic!("{}", e),
-            };
-            let mut client_rpc = Rpc::wallet(&btc_config, CLIENT).unwrap();
-            let client_addr = client_rpc.gen_addr().unwrap();
-            if client_rpc.get_balance().unwrap() < min_fund {
-                println!("Client need a minimum of {} BTC to run this test, 
send coins to this address: {}", min_fund.as_btc(), client_addr);
-                print_now("Waiting for fund:");
-                while client_rpc.get_balance().unwrap() < min_fund {
-                    client_rpc.wait_for_new_block().unwrap();
-                    print_now(".");
-                }
-            }
-            let mut since = client_rpc.list_since_block(None, 
1).unwrap().lastblock;
-            // Load wire
-            let mut wire_rpc = Rpc::wallet(&btc_config, WIRE).unwrap();
-            let wire_addr = wire_rpc.gen_addr().unwrap();
-
-            print_now("Wait for pending transactions mining:");
-            'l: loop {
-                let sync = client_rpc.list_since_block(Some(&since), 
1).unwrap();
-                let sync2 = wire_rpc.list_since_block(Some(&since), 
1).unwrap();
-                since = sync.lastblock;
-                for tx in sync
-                    .transactions
-                    .into_iter()
-                    .chain(sync2.transactions.into_iter())
-                {
-                    if tx.confirmations == 0 {
-                        rpc.wait_for_new_block().unwrap();
-                        print_now(".");
-                        continue 'l;
-                    }
-                }
-                break;
-            }
-            println!("");
-
-            // Load balances
-            let client_balance = client_rpc.get_balance().unwrap();
-            let wire_balance = wire_rpc.get_balance().unwrap();
-            // Test amount
-            let test_amount = Amount::from_sat(2000);
-            let min_send_amount = rpc_utils::segwit_min_amount(); // To small 
to send back
-            let min_bounce_amount = rpc_utils::segwit_min_amount() + 
Amount::from_sat(999); // To small after bounce fee
-            let taler_test_amount = 
btc_to_taler(&test_amount.to_signed().unwrap());
-
-            println!("Send transaction");
-            let reserve_pub_key = rand_slice();
-            let deposit_id = client_rpc
-                .send_segwit_key(&wire_addr, &test_amount, &reserve_pub_key)
-                .unwrap();
-            let bounce_min_id = client_rpc
-                .send(&wire_addr, &min_bounce_amount, None, false)
-                .unwrap();
-            let send_min_id = client_rpc
-                .send(&wire_addr, &min_send_amount, None, false)
-                .unwrap();
-            let bounce_id = client_rpc
-                .send(&wire_addr, &test_amount, None, false)
-                .unwrap();
-            let client_sent_amount_cost = test_amount
-                + min_send_amount * 2
-                + min_bounce_amount
-                + min_send_amount
-                + test_amount;
-            let client_sent_fees_cost: Amount = [deposit_id, bounce_min_id, 
send_min_id, bounce_id]
-                .into_iter()
-                .map(|id| 
unsigned(client_rpc.get_tx(&id).unwrap().fee.unwrap()))
-                .reduce(|acc, i| acc + i)
-                .unwrap();
-            let new_balance = client_rpc.get_balance().unwrap();
-            assert_eq!(
-                client_balance - client_sent_amount_cost - 
client_sent_fees_cost,
-                new_balance
-            );
-
-            print_now("Wait for client mining and bounce:");
-            let mut pending = true;
-            let mut bounced_id = None;
-            while pending || bounced_id.is_none() {
-                pending = false;
-                std::thread::sleep(Duration::from_secs(1));
-                rpc.wait_for_new_block().unwrap();
-                print_now(".");
-                let sync = client_rpc.list_since_block(Some(&since), 
1).unwrap();
-                for tx in sync.transactions {
-                    if tx.confirmations == 0 {
-                        pending = true;
-                    } else if tx.category == Category::Receive {
-                        let (_, metadata) = 
client_rpc.get_tx_op_return(&tx.txid).unwrap();
-                        let metadata = OutMetadata::decode(&metadata).unwrap();
-                        match metadata {
-                            OutMetadata::Withdraw { .. } => {}
-                            OutMetadata::Bounce { bounced } => {
-                                if bounced == bounce_id {
-                                    bounced_id.replace(tx.txid);
-                                } else if bounced == send_min_id {
-                                    panic!("Bounced send min");
-                                } else if bounced == bounce_min_id {
-                                    panic!("Bounced bounce min");
-                                }
-                            }
-                        }
-                    }
-                }
-                since = sync.lastblock;
-            }
-            println!("");
-
-            println!("Check balance");
-            let new_client_balance = client_rpc.get_balance().unwrap();
-            let new_wire_balance = wire_rpc.get_balance().unwrap();
-            let bounced = client_rpc.get_tx(&bounced_id.unwrap()).unwrap();
-            assert_eq!(
-                client_balance - client_sent_amount_cost - 
client_sent_fees_cost
-                    + unsigned(bounced.amount),
-                new_client_balance
-            );
-            assert_eq!(
-                wire_balance + test_amount + min_bounce_amount + 
min_send_amount + bounce_fee,
-                new_wire_balance
-            );
-
-            println!("Check history");
-            let history: IncomingHistory = 
ureq::get(&format!("{}/history/incoming", base_url))
-                .query("delta", "-5")
-                .call()
-                .unwrap()
-                .into_json()
-                .unwrap();
-            assert!(history
-                .incoming_transactions
-                .iter()
-                .find(|h| {
-                    matches!(
-                        h,
-                        IncomingBankTransaction::IncomingReserveTransaction {
-                            reserve_pub,
-                            amount,
-                            ..
-                        } if reserve_pub == &Base32::from(reserve_pub_key) && 
amount == &taler_test_amount
-                    )
-                })
-                .is_some());
-
-            println!("Get back some money");
-            let url = Url::parse("ftp://example.com";).unwrap();
-            let wtid = rand_slice();
-            ureq::post(&format!("{}/transfer", base_url))
-                .send_json(TransferRequest {
-                    request_uid: Base32::from(rand_slice()),
-                    amount: taler_test_amount.clone(),
-                    exchange_base_url: url.clone(),
-                    wtid: Base32::from(wtid),
-                    credit_account: btc_payto_url(&client_addr),
-                })
-                .unwrap();
-
-            print_now("Wait for wire mining:");
-            std::thread::sleep(Duration::from_secs(1));
-            'l1: loop {
-                let sync = wire_rpc.list_since_block(Some(&since), 1).unwrap();
-                since = sync.lastblock;
-                for tx in sync.transactions {
-                    if tx.confirmations == 0 {
-                        rpc.wait_for_new_block().unwrap();
-                        print_now(".");
-                        continue 'l1;
-                    }
-                }
-                break;
-            }
-            println!("");
-
-            println!("Check balances");
-            let last_client_balance = client_rpc.get_balance().unwrap();
-            assert_eq!(new_client_balance + test_amount, last_client_balance);
-
-            println!("Check history");
-            let history: OutgoingHistory = 
ureq::get(&format!("{}/history/outgoing", base_url))
-                .query("delta", "-5")
-                .call()
-                .unwrap()
-                .into_json()
-                .unwrap();
-            assert!(history
-                .outgoing_transactions
-                .iter()
-                .find(|h| {
-                    h.wtid == Base32::from(wtid)
-                        && h.exchange_base_url == url
-                        && h.amount == taler_test_amount
-                })
-                .is_some());
-        }
+        "BTC" => btc_test(args.config.as_deref(), &base_url),
         _ => unimplemented!(),
     }
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]