[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-depolymerization] branch master updated (59faf13 -> 0412d20),
gnunet <=