gnunet-svn
[Top][All Lists]
Advanced

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

[taler-depolymerization] branch master updated (59faf13 -> 0412d20)


From: gnunet
Subject: [taler-depolymerization] branch master updated (59faf13 -> 0412d20)
Date: Mon, 24 Jan 2022 16:11:55 +0100

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

antoine pushed a change to branch master
in repository depolymerization.

    from 59faf13  Improve docuementation and require maxtxfee bitcoin config
     new 0edd2ff  Ergonomic sql extraction
     new 42b2bc5  Improve error handling
     new 0412d20  Update dependencies

The 3 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                         | 25 ++++++++-------
 README.md                          |  2 +-
 btc-wire/Cargo.toml                |  2 +-
 btc-wire/src/bin/btc-wire-utils.rs |  6 ++--
 btc-wire/src/fail_point.rs         |  8 +++--
 btc-wire/src/loops.rs              | 19 +++++++++++
 btc-wire/src/loops/analysis.rs     |  4 ++-
 btc-wire/src/loops/listener.rs     |  4 ++-
 btc-wire/src/loops/worker.rs       | 66 +++++++++++++++++++-------------------
 btc-wire/src/main.rs               |  1 +
 btc-wire/src/sql.rs                | 51 +++++++++++++++++++++++++++++
 makefile                           |  1 +
 taler-common/Cargo.toml            |  2 ++
 taler-common/src/lib.rs            |  1 +
 taler-common/src/sql.rs            | 49 ++++++++++++++++++++++++++++
 test/btc/bumpfee.sh                |  1 -
 test/btc/{bumpfee.sh => maxfee.sh} | 58 +++++++++------------------------
 test/conf/bitcoin.conf             |  2 +-
 wire-gateway/Cargo.toml            |  2 +-
 wire-gateway/src/main.rs           | 66 ++++++++++++--------------------------
 20 files changed, 225 insertions(+), 145 deletions(-)
 create mode 100644 btc-wire/src/sql.rs
 create mode 100644 taler-common/src/sql.rs
 copy test/btc/{bumpfee.sh => maxfee.sh} (51%)

diff --git a/Cargo.lock b/Cargo.lock
index 44fe3a9..964143b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -463,9 +463,9 @@ checksum = 
"4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
 
 [[package]]
 name = "fastrand"
-version = "1.6.0"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
 dependencies = [
  "instant",
 ]
@@ -805,9 +805,9 @@ checksum = 
"eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
 
 [[package]]
 name = "listenfd"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "fe05ca4da1db151e4cfed8dfd45438047aee112e43656c0963b6579e443bf22a"
+checksum = "c02b14f35d9f5f082fd0b1b34aa0ef32e3354c859c721d7f3325b3f79a42ba54"
 dependencies = [
  "libc",
  "uuid",
@@ -1147,9 +1147,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
+checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
 dependencies = [
  "proc-macro2",
 ]
@@ -1324,9 +1324,9 @@ checksum = 
"568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
 
 [[package]]
 name = "serde"
-version = "1.0.134"
+version = "1.0.135"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "96b3c34c1690edf8174f5b289a336ab03f568a4460d8c6df75f2f3a692b3bc6a"
+checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b"
 dependencies = [
  "serde_derive",
 ]
@@ -1343,9 +1343,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.134"
+version = "1.0.135"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "784ed1fbfa13fe191077537b0d70ec8ad1e903cfe04831da608aa36457cb653d"
+checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1354,9 +1354,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.75"
+version = "1.0.78"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
+checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
 dependencies = [
  "itoa 1.0.1",
  "ryu",
@@ -1488,6 +1488,7 @@ dependencies = [
  "base32",
  "flexi_logger",
  "log",
+ "postgres",
  "rust-ini",
  "serde",
  "serde_json",
diff --git a/README.md b/README.md
index 5e3b6e8..53b2009 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ done.
 [depolymerizer-___]
 # Number of requests to serve before gateway shutdown (0 mean never)
 HTTP_LIFETIME  = 0
-# Number of done worker's loops before wire implementation shutdown (0 mean 
never)
+# Number of worker's loops before wire implementation shutdown (0 mean never)
 WIRE_LIFETIME  = 0
 ```
 
diff --git a/btc-wire/Cargo.toml b/btc-wire/Cargo.toml
index 3796da8..019eb09 100644
--- a/btc-wire/Cargo.toml
+++ b/btc-wire/Cargo.toml
@@ -21,7 +21,7 @@ bech32 = "0.8.1"
 # Secure random
 rand = { version = "0.8.4", features = ["getrandom"] }
 # Fast insecure random
-fastrand = "1.6.0"
+fastrand = "1.7.0"
 # Serialization library
 serde = { version = "1.0.133", features = ["derive"] }
 serde_json = "1.0.75"
diff --git a/btc-wire/src/bin/btc-wire-utils.rs 
b/btc-wire/src/bin/btc-wire-utils.rs
index 02db643..7f38033 100644
--- a/btc-wire/src/bin/btc-wire-utils.rs
+++ b/btc-wire/src/bin/btc-wire-utils.rs
@@ -115,9 +115,9 @@ impl App {
             }
         }
         let mut wallet = BtcRpc::wallet(&self.config, name).unwrap();
-        let addr = wallet
-            .get_new_address()
-            .expect(&format!("Failed to get wallet address {}", name));
+        let addr = wallet.get_new_address().unwrap_or_else(|_| {
+            panic!("Failed to get wallet address {}", name)
+        });
         (wallet, addr)
     }
 
diff --git a/btc-wire/src/fail_point.rs b/btc-wire/src/fail_point.rs
index 0579631..58d894f 100644
--- a/btc-wire/src/fail_point.rs
+++ b/btc-wire/src/fail_point.rs
@@ -13,12 +13,16 @@
   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/>
 */
+#[derive(Debug, thiserror::Error)]
+#[error("{0}")]
+pub struct Injected(&'static str);
+
 /// Inject random failure when 'fail' feature is used
 #[allow(unused_variables)]
-pub fn fail_point(msg: &'static str, prob: f32) -> Result<(), &'static str> {
+pub fn fail_point(msg: &'static str, prob: f32) -> Result<(), Injected> {
     #[cfg(feature = "fail")]
     return if fastrand::f32() < prob {
-        Err(msg)
+        Err(Injected(msg))
     } else {
         Ok(())
     };
diff --git a/btc-wire/src/loops.rs b/btc-wire/src/loops.rs
index 5e80da0..6009c59 100644
--- a/btc-wire/src/loops.rs
+++ b/btc-wire/src/loops.rs
@@ -13,6 +13,25 @@
   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 btc_wire::rpc;
+
+use crate::fail_point::Injected;
+
 pub mod analysis;
 pub mod listener;
 pub mod worker;
+
+#[derive(Debug, thiserror::Error)]
+pub enum LoopError {
+    #[error(transparent)]
+    RPC(#[from] rpc::Error),
+    #[error(transparent)]
+    DB(#[from] postgres::Error),
+    #[error("Another btc_wire process is running concurrently")]
+    Concurrency,
+    #[error(transparent)]
+    Injected(#[from] Injected),
+}
+
+pub type LoopResult<T> = Result<T, LoopError>;
\ No newline at end of file
diff --git a/btc-wire/src/loops/analysis.rs b/btc-wire/src/loops/analysis.rs
index 086d205..2981b50 100644
--- a/btc-wire/src/loops/analysis.rs
+++ b/btc-wire/src/loops/analysis.rs
@@ -27,6 +27,8 @@ use crate::{
     WireState,
 };
 
+use super::LoopResult;
+
 /// Analyse blockchain behavior and adapt confirmations in real time
 pub fn analysis(
     mut rpc: AutoReconnectRPC,
@@ -39,7 +41,7 @@ pub fn analysis(
     loop {
         let rpc = rpc.client();
         let db = db.client();
-        let result: Result<(), Box<dyn std::error::Error>> = (|| {
+        let result: LoopResult<()> = (|| {
             // Register as listener
             db.batch_execute("LISTEN new_block")?;
             loop {
diff --git a/btc-wire/src/loops/listener.rs b/btc-wire/src/loops/listener.rs
index 85210b4..66defc7 100644
--- a/btc-wire/src/loops/listener.rs
+++ b/btc-wire/src/loops/listener.rs
@@ -17,12 +17,14 @@ use taler_common::log::log::error;
 
 use crate::reconnect::{AutoReconnectRPC, AutoReconnectSql};
 
+use super::LoopResult;
+
 /// Wait for new block and notify arrival with postgreSQL notifications
 pub fn block_listener(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql) {
     loop {
         let rpc = rpc.client();
         let db = db.client();
-        let result: Result<(), Box<dyn std::error::Error>> = (|| loop {
+        let result: LoopResult<()> = (|| loop {
             rpc.wait_for_new_block(0)?;
             db.execute("NOTIFY new_block", &[])?;
         })();
diff --git a/btc-wire/src/loops/worker.rs b/btc-wire/src/loops/worker.rs
index f66d85e..d30faa5 100644
--- a/btc-wire/src/loops/worker.rs
+++ b/btc-wire/src/loops/worker.rs
@@ -16,12 +16,11 @@
 use std::{
     collections::{HashMap, HashSet},
     fmt::Write,
-    str::FromStr,
     sync::atomic::Ordering,
     time::{Duration, SystemTime},
 };
 
-use bitcoin::{hashes::Hash, Address, Amount as BtcAmount, BlockHash, Txid};
+use bitcoin::{hashes::Hash, Amount as BtcAmount, BlockHash, Txid};
 use btc_wire::{
     rpc::{self, BtcRpc, Category, ErrorCode},
     rpc_utils::sender_address,
@@ -29,21 +28,24 @@ use btc_wire::{
 };
 use postgres::{fallible_iterator::FallibleIterator, Client};
 use taler_common::{
-    api_common::{base32, Amount},
+    api_common::base32,
     config::Config,
     log::log::{error, info, warn},
+    sql::{sql_array, sql_url},
 };
-use url::Url;
 
 use crate::{
     fail_point::fail_point,
     info::{decode_info, encode_info, Info},
     reconnect::{AutoReconnectRPC, AutoReconnectSql},
+    sql::{sql_addr, sql_btc_amount, sql_txid},
     status::{BounceStatus, TxStatus},
-    taler_util::{btc_payto_addr, btc_payto_url, btc_to_taler, taler_to_btc},
+    taler_util::{btc_payto_url, btc_to_taler},
     WireState,
 };
 
+use super::{LoopError, LoopResult};
+
 /// Listen for new proposed transactions and announce them on the bitcoin 
network
 pub fn worker(
     mut rpc: AutoReconnectRPC,
@@ -71,7 +73,7 @@ pub fn worker(
         let rpc = rpc.client();
         let db = db.client();
 
-        let result: Result<(), Box<dyn std::error::Error>> = (|| {
+        let result: LoopResult<()> = (|| {
             // Listen to all channels
             db.batch_execute("LISTEN new_block; LISTEN new_tx")?;
             // Wait for the next notification
@@ -98,7 +100,7 @@ pub fn worker(
             let row = db.query_one("SELECT pg_try_advisory_lock(42)", &[])?;
             let locked: bool = row.get(0);
             if !locked {
-                return Err("Another btc_wire process is running 
concurrently".into());
+                return Err(LoopError::Concurrency);
             }
 
             // Sync chain
@@ -121,8 +123,14 @@ pub fn worker(
         })();
         if let Err(e) = result {
             error!("worker: {}", e);
-            // On failure retry without waiting for notifications
-            skip_notification = true;
+            // 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
+            // approach is to wait for the next loop when an RPC error is 
caught to prevent endless logged errors.
+            skip_notification = !matches!(
+                e,
+                LoopError::RPC(rpc::Error::RPC { .. } | rpc::Error::Bitcoin(_))
+            );
         } else {
             skip_notification = false;
         }
@@ -130,11 +138,7 @@ pub fn worker(
 }
 
 /// Send a transaction on the blockchain, return true if more transactions 
with the same status remains
-fn send(
-    db: &mut Client,
-    rpc: &mut BtcRpc,
-    status: TxStatus,
-) -> Result<bool, Box<dyn std::error::Error>> {
+fn send(db: &mut Client, rpc: &mut BtcRpc, status: TxStatus) -> 
LoopResult<bool> {
     assert!(status == TxStatus::Delayed || status == TxStatus::Requested);
     // We rely on the advisory lock to ensure we are the only one sending 
transactions
     let row = db.query_opt(
@@ -143,14 +147,11 @@ fn send(
     )?;
     if let Some(row) = &row {
         let id: i32 = row.get(0);
-        let amount = taler_to_btc(&Amount::from_str(row.get(1))?)?;
-        let wtid: &[u8] = row.get(2);
-        let addr: Address = btc_payto_addr(&Url::parse(row.get(3))?)?;
-        let exchange_base_url: Url = Url::parse(row.get(4))?;
-        let info = Info::Transaction {
-            wtid: wtid.try_into()?,
-            url: exchange_base_url,
-        };
+        let amount = sql_btc_amount(row, 1);
+        let wtid: [u8; 32] = sql_array(row, 2);
+        let addr = sql_addr(row, 3);
+        let url = sql_url(row, 4);
+        let info = Info::Transaction { wtid, url };
         let metadata = encode_info(&info);
 
         match rpc.send_op_return(&addr, &amount, &metadata, false, true) {
@@ -161,7 +162,7 @@ fn send(
                     &[&(TxStatus::Sent as i16), &tx_id.as_ref(), &id],
                 )?;
                 let amount = btc_to_taler(&amount.to_signed().unwrap());
-                info!(">> {} {} in {} to {}", amount, base32(wtid), tx_id, 
addr);
+                info!(">> {} {} in {} to {}", amount, base32(&wtid), tx_id, 
addr);
             }
             Err(e) => {
                 db.execute(
@@ -181,7 +182,7 @@ fn bounce(
     rpc: &mut BtcRpc,
     status: BounceStatus,
     fee: &BtcAmount,
-) -> Result<bool, Box<dyn std::error::Error>> {
+) -> LoopResult<bool> {
     assert!(status == BounceStatus::Delayed || status == 
BounceStatus::Requested);
     // We rely on the advisory lock to ensure we are the only one sending 
transactions
     let row = db.query_opt(
@@ -190,7 +191,7 @@ fn bounce(
     )?;
     if let Some(row) = &row {
         let id: i32 = row.get(0);
-        let bounced: Txid = Txid::from_slice(row.get(1))?;
+        let bounced: Txid = sql_txid(row, 1);
         let info = Info::Bounce { bounced };
         let metadata = encode_info(&info);
 
@@ -241,7 +242,7 @@ fn sync_chain(
     config: &Config,
     state: &WireState,
     status: &mut bool,
-) -> Result<bool, Box<dyn std::error::Error>> {
+) -> LoopResult<bool> {
     // Get stored last_hash
     let last_hash = last_hash(db)?;
     let min_confirmations = state.confirmation.load(Ordering::SeqCst);
@@ -325,7 +326,7 @@ fn sync_chain_removed(
     rpc: &mut BtcRpc,
     db: &mut Client,
     min_confirmations: i32,
-) -> Result<bool, Box<dyn std::error::Error>> {
+) -> LoopResult<bool> {
     // Removed transactions are correctness issue in only two cases:
     // - An incoming valid transaction considered confirmed in the database
     // - An incoming invalid transactions already bounced
@@ -357,8 +358,7 @@ fn sync_chain_removed(
                         "SELECT txid FROM bounce WHERE bounced=$1 AND txid IS 
NOT NULL",
                         &[&id.as_ref()],
                     )? {
-                        let txid = Txid::from_slice(row.get(0)).unwrap();
-                        blocking_bounce.push((txid, id));
+                        blocking_bounce.push((sql_txid(&row, 0), id));
                     } else {
                         // Remove transaction from bounce table
                         db.execute("DELETE FROM bounce WHERE bounced=$1", 
&[&id.as_ref()])?;
@@ -398,7 +398,7 @@ fn sync_chain_outgoing(
     rpc: &mut BtcRpc,
     db: &mut Client,
     config: &Config,
-) -> Result<(), Box<dyn std::error::Error>> {
+) -> LoopResult<()> {
     match rpc
         .get_tx_op_return(id)
         .map(|(full, bytes)| (full, decode_info(&bytes)))
@@ -452,7 +452,7 @@ fn sync_chain_outgoing(
                             }
                             TxStatus::Sent => {
                                 if let Some(txid) = full.replaces_txid {
-                                    let stored_id: Txid = 
Txid::from_slice(row.get(2)).unwrap();
+                                    let stored_id = sql_txid(&row, 2);
                                     if txid == stored_id {
                                         let nb_row = db.execute(
                                             "UPDATE tx_out SET txid=$1 WHERE 
txid=$2",
@@ -496,7 +496,7 @@ fn sync_chain_outgoing(
                                 .unwrap()
                                 .as_secs();
                             if now - full.time > delay as u64 {
-                                let bump = rpc.bump_fee(&id)?;
+                                let bump = rpc.bump_fee(id)?;
                                 fail_point("(injected) fail bump", 0.3)?;
                                 db.execute(
                                     "UPDATE tx_out SET txid=$1 WHERE txid=$2",
@@ -576,7 +576,7 @@ fn sync_chain_incoming_confirmed(
     id: &Txid,
     rpc: &mut BtcRpc,
     db: &mut Client,
-) -> Result<(), Box<dyn std::error::Error>> {
+) -> Result<(), LoopError> {
     match rpc.get_tx_segwit_key(id) {
         Ok((full, reserve_pub)) => {
             // Store transactions in database
diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs
index e551735..218ada8 100644
--- a/btc-wire/src/main.rs
+++ b/btc-wire/src/main.rs
@@ -31,6 +31,7 @@ mod loops;
 mod reconnect;
 mod status;
 mod taler_util;
+mod sql;
 
 pub struct WireState {
     confirmation: AtomicU16,
diff --git a/btc-wire/src/sql.rs b/btc-wire/src/sql.rs
new file mode 100644
index 0000000..343f812
--- /dev/null
+++ b/btc-wire/src/sql.rs
@@ -0,0 +1,51 @@
+/*
+  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, Address, Amount as BtcAmount, Txid};
+use postgres::Row;
+use taler_common::sql::{sql_amount, sql_url};
+
+use crate::taler_util::{btc_payto_addr, taler_to_btc};
+
+pub fn sql_btc_amount(row: &Row, idx: usize) -> BtcAmount {
+    let amount = sql_amount(row, idx);
+    taler_to_btc(&amount).unwrap_or_else(|_| {
+        panic!(
+            "Database invariant: expected an bitcoin amount got {}",
+            amount
+        )
+    })
+}
+
+pub fn sql_addr(row: &Row, idx: usize) -> Address {
+    let url = sql_url(row, idx);
+    btc_payto_addr(&url).unwrap_or_else(|_| {
+        panic!(
+            "Database invariant: expected an bitcoin payto url got {}",
+            url
+        )
+    })
+}
+
+pub fn sql_txid(row: &Row, idx: usize) -> Txid {
+    let slice: &[u8] = row.get(idx);
+    Txid::from_slice(slice).unwrap_or_else(|_| {
+        panic!(
+            "Database invariant: expected a transaction if got an array of 
{}B",
+            slice.len()
+        )
+    })
+}
diff --git a/makefile b/makefile
index e754987..deb9745 100644
--- a/makefile
+++ b/makefile
@@ -15,6 +15,7 @@ test_btc:
        test/btc/hell.sh
        test/btc/analysis.sh
        test/btc/bumpfee.sh
+       test/btc/maxfee.sh
        test/btc/config.sh
 
 test: install test_gateway test_btc
\ No newline at end of file
diff --git a/taler-common/Cargo.toml b/taler-common/Cargo.toml
index 5136126..8468564 100644
--- a/taler-common/Cargo.toml
+++ b/taler-common/Cargo.toml
@@ -28,3 +28,5 @@ flexi_logger = { version = "0.22.2", default-features = 
false, features = [
 ] }
 # Local timz
 time = { version = "0.3.5", features = ["formatting", "macros"] }
+# Postgres client
+postgres = "0.19.2"
diff --git a/taler-common/src/lib.rs b/taler-common/src/lib.rs
index 95c143a..d935941 100644
--- a/taler-common/src/lib.rs
+++ b/taler-common/src/lib.rs
@@ -20,3 +20,4 @@ pub mod api_wire;
 pub mod config;
 pub mod error_codes;
 pub mod log;
+pub mod sql;
\ No newline at end of file
diff --git a/taler-common/src/sql.rs b/taler-common/src/sql.rs
new file mode 100644
index 0000000..ca34909
--- /dev/null
+++ b/taler-common/src/sql.rs
@@ -0,0 +1,49 @@
+/*
+  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::str::FromStr;
+
+use postgres::Row;
+use url::Url;
+
+use crate::api_common::{Amount, SafeUint64};
+
+pub fn sql_url(row: &Row, idx: usize) -> Url {
+    let str: &str = row.get(idx);
+    Url::from_str(str).unwrap_or_else(|_| panic!("Database invariant: expected 
an url got {}", str))
+}
+
+pub fn sql_amount(row: &Row, idx: usize) -> Amount {
+    let str: &str = row.get(idx);
+    Amount::from_str(str)
+        .unwrap_or_else(|_| panic!("Database invariant: expected an amount got 
{}", str))
+}
+
+pub fn sql_array<const N: usize>(row: &Row, idx: usize) -> [u8; N] {
+    let slice: &[u8] = row.get(idx);
+    slice.try_into().unwrap_or_else(|_| {
+        panic!(
+            "Database invariant: expected an byte array of {}B for {}B",
+            N,
+            slice.len()
+        )
+    })
+}
+
+pub fn sql_safe_u64(row: &Row, idx: usize) -> SafeUint64 {
+    let id: i32 = row.get(idx);
+    SafeUint64::try_from(id as u64).unwrap()
+}
diff --git a/test/btc/bumpfee.sh b/test/btc/bumpfee.sh
index e710bfe..6dcdd9e 100644
--- a/test/btc/bumpfee.sh
+++ b/test/btc/bumpfee.sh
@@ -7,7 +7,6 @@ set -eu
 source "${BASH_SOURCE%/*}/../common.sh"
 SCHEMA=btc.sql
 CONFIG=taler_bump.conf
-RUST_BACKTRACE=full
 
 echo  "----- Setup -----"
 echo "Load config file"
diff --git a/test/btc/bumpfee.sh b/test/btc/maxfee.sh
similarity index 51%
copy from test/btc/bumpfee.sh
copy to test/btc/maxfee.sh
index e710bfe..4bb40c9 100644
--- a/test/btc/bumpfee.sh
+++ b/test/btc/maxfee.sh
@@ -6,8 +6,6 @@ set -eu
 
 source "${BASH_SOURCE%/*}/../common.sh"
 SCHEMA=btc.sql
-CONFIG=taler_bump.conf
-RUST_BACKTRACE=full
 
 echo  "----- Setup -----"
 echo "Load config file"
@@ -26,7 +24,6 @@ echo ""
 
 SEQ="seq 10 30"
 
-
 echo -n "Making wire transfer to exchange:"
 for n in `$SEQ`; do
     btc-wire-utils -d $BTC_DIR transfer 0.$n > /dev/null
@@ -36,32 +33,10 @@ next_btc # Trigger btc_wire
 check_balance 5.79983389 4.20000000
 echo " OK"
 
-echo "----- Bump fee -----"
-
-echo -n "Making wire transfer from exchange:"
-taler-exchange-wire-gateway-client \
-    -b $BANK_ENDPOINT \
-    -C payto://bitcoin/$CLIENT \
-    -a BTC:0.004 > /dev/null
-sleep 1
-check_balance 5.79983389 4.19599801
-echo " OK"
-
-echo -n "Abandon pending transaction:"
-restart_btc -minrelaytxfee=0.0001
-echo " OK"
-
-echo -n "Check bump:"
-sleep 6
-mine_btc
-check_balance 5.80383389 4.19598010
-echo " OK"
-
-echo "----- Bump stress -----"
+echo "----- Too high fees -----"
 
-echo -n "Replace btc_wire with stressed btc_wire"
-kill $WIRE_PID
-stress_btc_wire
+echo -n "Set up node"
+restart_btc -maxtxfee=0.0000001 -minrelaytxfee=0.0000001
 echo " OK"
 
 echo -n "Making wire transfer from exchange:"
@@ -69,26 +44,25 @@ for n in `$SEQ`; do
     taler-exchange-wire-gateway-client \
         -b $BANK_ENDPOINT \
         -C payto://bitcoin/$CLIENT \
-        -a BTC:0.00$n > /dev/null
+        -a BTC:0.0$n > /dev/null
 done
 sleep 5
-check_balance 5.80383389 4.15356220
+mine_btc
 echo " OK"
 
-echo -n "Abandon pending transaction:"
-restart_btc -minrelaytxfee=0.0002
+echo -n "Check no transaction have been made"
+check_balance 5.79983389 4.20000000
 echo " OK"
 
-echo -n "Check bump:"
-sleep 2
-mine_btc
-sleep 2
-mine_btc
-sleep 2
-mine_btc
-sleep 2
-mine_btc
-check_balance 5.84583389 4.15314430
+echo "----- Good fees -----"
+
+echo -n "Set up node"
+restart_btc
+echo " OK"
+
+echo -n "Check transaction have been made"
+sleep 6
+check_balance 5.79983389 3.77995821
 echo " OK"
 
 echo "All tests passed!"
\ No newline at end of file
diff --git a/test/conf/bitcoin.conf b/test/conf/bitcoin.conf
index 6f85b36..b824b91 100644
--- a/test/conf/bitcoin.conf
+++ b/test/conf/bitcoin.conf
@@ -1,6 +1,6 @@
 regtest=1
 txindex=1
-maxtxfee=0.00002000
+maxtxfee=0.01
 fallbackfee=0.00000001
 
 [regtest]
diff --git a/wire-gateway/Cargo.toml b/wire-gateway/Cargo.toml
index 0fc4c86..d798d17 100644
--- a/wire-gateway/Cargo.toml
+++ b/wire-gateway/Cargo.toml
@@ -34,7 +34,7 @@ tokio-postgres = { version = "0.7.5" }
 postgres = { version = "0.19.2" }
 deadpool-postgres = "0.10.1"
 # Socket activation
-listenfd = "0.4.0"
+listenfd = "0.5.0"
 # Taler libs
 taler-common = { path = "../taler-common" }
 
diff --git a/wire-gateway/src/main.rs b/wire-gateway/src/main.rs
index 1a979ff..8ff5fd4 100644
--- a/wire-gateway/src/main.rs
+++ b/wire-gateway/src/main.rs
@@ -30,13 +30,14 @@ use std::{
     time::{Duration, Instant},
 };
 use taler_common::{
-    api_common::{Amount, SafeUint64, ShortHashCode, Timestamp},
+    api_common::{ShortHashCode, Timestamp},
     api_wire::{
         HistoryParams, IncomingBankTransaction, IncomingHistory, 
OutgoingBankTransaction,
         OutgoingHistory, TransferRequest, TransferResponse,
     },
     error_codes::ErrorCode,
     log::log::{error, info, log, Level},
+    sql::{sql_amount, sql_array, sql_safe_u64, sql_url},
     url::Url,
 };
 use tokio::sync::Notify;
@@ -292,14 +293,10 @@ async fn router(
             if let Some(row) = row {
                 let prev = TransferRequest {
                     request_uid: request.request_uid.clone(),
-                    amount: Amount::from_str(row.get(0)).unwrap(),
-                    exchange_base_url: Url::parse(row.get(1)).unwrap(),
-                    wtid: {
-                        let slice: &[u8] = row.get(2);
-                        let array: [u8; 32] = slice.try_into().unwrap();
-                        ShortHashCode::from(array)
-                    },
-                    credit_account: Url::parse(row.get(3)).unwrap(),
+                    amount: sql_amount(&row, 0),
+                    exchange_base_url: sql_url(&row, 1),
+                    wtid: ShortHashCode::from(sql_array(&row, 2)),
+                    credit_account: sql_url(&row, 3),
                 };
                 if prev == request {
                     // Idempotence
@@ -308,10 +305,7 @@ async fn router(
                         StatusCode::OK,
                         &TransferResponse {
                             timestamp: Timestamp::Time(row.get(5)),
-                            row_id: {
-                                let id: i32 = row.get(4);
-                                SafeUint64::try_from(id as u64).unwrap()
-                            },
+                            row_id: sql_safe_u64(&row, 4),
                         },
                     )
                     .await
@@ -333,10 +327,7 @@ async fn router(
                 StatusCode::OK,
                 &TransferResponse {
                     timestamp,
-                    row_id: {
-                        let id: i32 = row.get(0);
-                        SafeUint64::try_from(id as u64).unwrap()
-                    },
+                    row_id: sql_safe_u64(&row, 0),
                 },
             )
             .await
@@ -361,19 +352,12 @@ async fn router(
                 )?
                 .into_iter()
                 .map(|row| IncomingBankTransaction::IncomingReserveTransaction 
{
-                    row_id: {
-                        let id: i32 = row.get(0);
-                        SafeUint64::try_from(id as u64).unwrap()
-                    },
+                    row_id: sql_safe_u64(&row, 0),
                     date: Timestamp::Time(row.get(1)),
-                    amount: Amount::from_str(row.get(2)).unwrap(),
-                    reserve_pub: {
-                        let slice: &[u8] = row.get(3);
-                        let array: [u8; 32] = slice.try_into().unwrap();
-                        ShortHashCode::from(array)
-                    },
-                    debit_account: Url::parse(row.get(4)).unwrap(),
-                    credit_account: Url::parse(row.get(5)).unwrap(),
+                    amount: sql_amount(&row, 2),
+                    reserve_pub: ShortHashCode::from(sql_array(&row, 3)),
+                    debit_account: sql_url(&row, 4),
+                    credit_account: sql_url(&row, 5),
                 })
                 .collect();
             encode_body(
@@ -406,20 +390,13 @@ async fn router(
                 )?
                 .into_iter()
                 .map(|row| OutgoingBankTransaction {
-                    row_id: {
-                        let id: i32 = row.get(0);
-                        SafeUint64::try_from(id as u64).unwrap()
-                    },
+                    row_id: sql_safe_u64(&row, 0),
                     date: Timestamp::Time(row.get(1)),
-                    amount: Amount::from_str(row.get(2)).unwrap(),
-                    wtid: {
-                        let slice : &[u8] = row.get(3);
-                        let array: [u8; 32] = slice.try_into().unwrap();
-                        ShortHashCode::from(array)
-                    },
-                    debit_account: Url::parse(row.get(4)).unwrap(),
-                    credit_account: Url::parse(row.get(5)).unwrap(),
-                    exchange_base_url: Url::parse(row.get(6)).unwrap(),
+                    amount: sql_amount(&row, 2),
+                    wtid: ShortHashCode::from(sql_array(&row, 3)),
+                    debit_account: sql_url(&row, 4),
+                    credit_account: sql_url(&row, 5),
+                    exchange_base_url:sql_url(&row, 6),
                 })
                 .collect();
             encode_body(
@@ -454,10 +431,7 @@ async fn router(
                 StatusCode::OK,
                 &TransferResponse {
                     timestamp,
-                    row_id: {
-                        let id: i32 = row.get(0);
-                        SafeUint64::try_from(id as u64).unwrap()
-                    },
+                    row_id: sql_safe_u64(&row, 0),
                 },
             )
             .await

-- 
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]