depolymerization

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

commit fe30526e0158774da8dbc52242a4e769746259d5
parent 8976614d20acbdd9f88a0e56eb8f9a8886501478
Author: Antoine A <>
Date:   Wed, 29 Dec 2021 17:33:35 +0100

btc-wire: test reconnect RPC

Diffstat:
Mbtc-wire/src/reconnect.rs | 4++--
Mbtc-wire/src/rpc.rs | 37++++++++++++++-----------------------
Mmakefile | 2+-
Mscript/setup.sh | 8--------
Ascript/test_btc_reconnect.sh | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dscript/test_recover_db.sh | 91-------------------------------------------------------------------------------
6 files changed, 114 insertions(+), 125 deletions(-)

diff --git a/btc-wire/src/reconnect.rs b/btc-wire/src/reconnect.rs @@ -34,7 +34,7 @@ impl AutoReconnectRPC { } }, Err(err) => { - error!("connect:RPC - {}", err); + error!("connect: RPC - {}", err); std::thread::sleep(delay); } } @@ -71,7 +71,7 @@ impl AutoReconnectSql { match Client::connect(config, NoTls) { Ok(new) => return new, Err(err) => { - error!("connect: RPC - {}", err); + error!("connect: DB - {}", err); std::thread::sleep(delay); } } diff --git a/btc-wire/src/rpc.rs b/btc-wire/src/rpc.rs @@ -3,8 +3,7 @@ use serde_json::{json, Value}; use std::{ fmt::Debug, io::{self, BufRead, BufReader, Write}, - net::{SocketAddr, TcpStream}, - time::Duration, + net::TcpStream, }; use crate::config::BitcoinConfig; @@ -51,11 +50,10 @@ pub type Result<T> = std::result::Result<T, Error>; const EMPTY: [(); 0] = []; pub struct BtcRpc { - addr: SocketAddr, path: String, id: u64, cookie: String, - conn: Option<BufReader<TcpStream>>, + conn: BufReader<TcpStream>, } impl BtcRpc { @@ -75,12 +73,15 @@ impl BtcRpc { }; let cookie_path = config.dir.join(".cookie"); let cookie = std::fs::read(cookie_path)?; + // Open connection + let sock = TcpStream::connect(config.addr)?; + let conn = BufReader::new(sock); + Ok(Self { - addr: config.addr, path, id: 0, cookie: format!("Basic {}", base64::encode(&cookie)), - conn: None, + conn, }) } @@ -88,18 +89,7 @@ impl BtcRpc { where T: serde::de::DeserializeOwned + Debug, { - if self.conn.is_none() { - // Some call might hang waiting for a new block to be mined - let timeout = Duration::from_secs(666); - - // Open connection - let sock = TcpStream::connect_timeout(&self.addr, timeout)?; - sock.set_read_timeout(Some(timeout))?; - sock.set_write_timeout(Some(timeout))?; - self.conn.replace(BufReader::new(sock)); - }; - let sock = self.conn.as_mut().unwrap(); - + // TODO rethink timeout let request = BtcRequest { method, id: self.id, @@ -111,7 +101,7 @@ impl BtcRpc { let mut buf = Vec::new(); // Write HTTP request { - let sock = sock.get_mut(); + let sock = self.conn.get_mut(); // Send HTTP request writeln!(buf, "POST {} HTTP/1.1\r", self.path)?; // Write headers @@ -121,15 +111,16 @@ impl BtcRpc { writeln!(buf, "Content-Length: {}\r", body.len())?; // Write separator writeln!(buf, "\r")?; - sock.write_all(&buf).unwrap(); + sock.write_all(&buf)?; buf.clear(); // Write body - sock.write_all(&body).unwrap(); + sock.write_all(&body)?; sock.flush().unwrap(); } // Skip response + let sock = &mut self.conn; loop { - let amount = sock.read_until(b'\n', &mut buf).unwrap(); + let amount = sock.read_until(b'\n', &mut buf)?; let sep = buf[..amount] == [b'\r', b'\n']; buf.clear(); if sep { @@ -137,7 +128,7 @@ impl BtcRpc { } } // Read body - let amount = sock.read_until(b'\n', &mut buf).unwrap(); + let amount = sock.read_until(b'\n', &mut buf)?; let response: BtcResponse<T> = serde_json::from_slice(&buf[..amount])?; assert_eq!(self.id, response.id); diff --git a/makefile b/makefile @@ -5,6 +5,6 @@ install: test: script/test_gateway.sh script/test_btc_wire.sh - script/test_recover_db.sh + script/test_btc_reconnect.sh script/test_btc_fail.sh script/test_btc_stress.sh \ No newline at end of file diff --git a/script/setup.sh b/script/setup.sh @@ -38,14 +38,6 @@ function setup_db() { psql $DB_URL < wire-gateway/db/schema.sql &> /dev/null } -function stop_db() { - pg_ctl stop -D $DB_DIR > /dev/null -} - -function start_db() { - pg_ctl start -D $DB_DIR > /dev/null -} - # Erase database function reset_db() { psql $DB_URL < wire-gateway/db/schema.sql > /dev/null diff --git a/script/test_btc_reconnect.sh b/script/test_btc_reconnect.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +## Check the capacity of wire_gateway and btc_wire to recover from database loss + +set -eu + +source "${BASH_SOURCE%/*}/setup.sh" + +echo "----- Setup -----" +echo "Load config file" +load_config +echo "Start database" +setup_db +echo "Start bitcoin node" +init_btc +echo "Start bitcoin regtest" +setup_btc +echo "Start btc-wire" +btc_wire +echo "Start gateway" +gateway +echo "" + +echo "----- With DB -----" +echo "Making wire transfer to exchange:" +btc-wire-cli -d $BTC_DIR transfer 0.000042 +next_btc +check_balance 9.99995009 0.00004200 +echo -n "Requesting exchange incoming transaction list:" +taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.000042 > /dev/null && echo " OK" || echo " Failed" + +echo "----- Without DB -----" + +echo "Stop database" +pg_ctl stop -D $DB_DIR > /dev/null +echo "Making incomplete wire transfer to exchange" +$BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.00042 &> /dev/null +echo "Making wire transfer to exchange:" +btc-wire-cli -d $BTC_DIR transfer 0.00004 +next_btc +check_balance 9.99948077 0.00050200 +echo "Stop bitcoin node" +PID=`jobs -p bitcoind` +kill $PID +wait $PID +echo -n "Requesting exchange incoming transaction list:" +taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i 2>&1 | grep -q "504" && echo " OK" || echo " Failed" + +echo "----- Reconnect DB -----" + +echo "Start database" +pg_ctl start -D $DB_DIR > /dev/null +echo "Start bitcoin node" +restart_btc +sleep 6 # Wait for connection to be available +echo -n "Requesting exchange incoming transaction list:" +taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.00004 > /dev/null && echo " OK" || echo " Failed" +echo -n "Making wire transfer from exchange:" +taler-exchange-wire-gateway-client \ + -b $BANK_ENDPOINT \ + -C payto://bitcoin/$CLIENT \ + -a BTC:0.00002 > /dev/null +sleep 1 +mine_btc +check_balance 9.99990892 0.00007001 +echo " OK" + +echo -n "Requesting exchange's outgoing transaction list:" +taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -o | grep BTC:0.00002 > /dev/null +echo " OK" + +echo "----- Recover DB -----" + +echo "Reset database" +reset_db # Clear database tables +mine_btc # Trigger worker +sleep 2 + +echo -n "Checking recover incoming transactions:" +ALL=`taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i`; +for amount in 0.000042 0.00004; do + echo $ALL | grep BTC:$amount > /dev/null && echo -n " OK" || echo -n " Failed" +done +echo "" + +echo -n "Requesting exchange's outgoing transaction list:" +ALL=`taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -o`; +for amount in 0.00002; do + echo $ALL | grep BTC:$amount > /dev/null && echo -n " OK" || echo -n " Failed" +done +echo "" + +# Balance should not have changed +check_balance 9.99990892 0.00007001 + +echo "All tests passed" +\ No newline at end of file diff --git a/script/test_recover_db.sh b/script/test_recover_db.sh @@ -1,90 +0,0 @@ -#!/bin/bash - -## Check the capacity of wire_gateway and btc_wire to recover from database loss - -set -eu - -source "${BASH_SOURCE%/*}/setup.sh" - -echo "----- Setup -----" -echo "Load config file" -load_config -echo "Start database" -setup_db -echo "Start bitcoin node" -init_btc -echo "Start bitcoin regtest" -setup_btc -echo "Start btc-wire" -btc_wire -echo "Start gateway" -gateway -echo "" - -echo "----- With DB -----" -echo "Making wire transfer to exchange:" -btc-wire-cli -d $BTC_DIR transfer 0.000042 -next_btc -check_balance 9.99995009 0.00004200 -echo -n "Requesting exchange incoming transaction list:" -taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.000042 > /dev/null && echo " OK" || echo " Failed" - -echo "----- Without DB -----" - -echo "Stop database" -stop_db -echo "Making incomplete wire transfer to exchange" -$BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.00042 &> /dev/null -echo "Making wire transfer to exchange:" -btc-wire-cli -d $BTC_DIR transfer 0.00004 -next_btc -check_balance 9.99948077 0.00050200 -echo -n "Requesting exchange incoming transaction list:" -taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i 2>&1 | grep -q "504" && echo " OK" || echo " Failed" - -echo "----- Reconnect DB -----" - -echo "Start database" -start_db -sleep 6 # Wait for connection to be available -echo -n "Requesting exchange incoming transaction list:" -taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.00004 > /dev/null && echo " OK" || echo " Failed" -echo -n "Making wire transfer from exchange:" -taler-exchange-wire-gateway-client \ - -b $BANK_ENDPOINT \ - -C payto://bitcoin/$CLIENT \ - -a BTC:0.00002 > /dev/null -sleep 1 -mine_btc -check_balance 9.99990892 0.00007001 -echo " OK" - -echo -n "Requesting exchange's outgoing transaction list:" -taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -o | grep BTC:0.00002 > /dev/null -echo " OK" - -echo "----- Recover DB -----" - -echo "Reset database" -reset_db # Clear database tables -mine_btc # Trigger worker -sleep 2 - -echo -n "Checking recover incoming transactions:" -ALL=`taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i`; -for amount in 0.000042 0.00004; do - echo $ALL | grep BTC:$amount > /dev/null && echo -n " OK" || echo -n " Failed" -done -echo "" - -echo -n "Requesting exchange's outgoing transaction list:" -ALL=`taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -o`; -for amount in 0.00002; do - echo $ALL | grep BTC:$amount > /dev/null && echo -n " OK" || echo -n " Failed" -done -echo "" - -# Balance should not have changed -check_balance 9.99990892 0.00007001 - -echo "All tests passed" -\ No newline at end of file