From cf984689d19c3a2f532ee0005dbcce19c87e59f3 Mon Sep 17 00:00:00 2001 From: Antoine A <> Date: Mon, 3 Jan 2022 02:14:52 +0100 Subject: Handle blockchain reorganisation --- Cargo.lock | 14 ++--- btc-wire/src/main.rs | 88 ++++++++++++++++++-------- makefile | 1 + script/setup.sh | 56 ++++++++++++++--- script/test_btc_fail.sh | 3 +- script/test_btc_fork.sh | 147 +++++++++++++++++++++++++++++++++++++++++++ script/test_btc_reconnect.sh | 6 +- script/test_btc_stress.sh | 7 ++- script/test_btc_wire.sh | 59 +++++++++++------ taler-api/src/api_common.rs | 4 +- test.conf | 2 +- 11 files changed, 316 insertions(+), 71 deletions(-) create mode 100644 script/test_btc_fork.sh diff --git a/Cargo.lock b/Cargo.lock index 21a833b..47de10e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,13 +651,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa 0.4.8", + "itoa 1.0.1", ] [[package]] @@ -1048,9 +1048,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" @@ -1689,9 +1689,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs index b078231..83c65fb 100644 --- a/btc-wire/src/main.rs +++ b/btc-wire/src/main.rs @@ -11,12 +11,13 @@ use postgres::{fallible_iterator::FallibleIterator, Client}; use rand::{rngs::OsRng, RngCore}; use reconnect::{AutoReconnectRPC, AutoReconnectSql}; use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, path::PathBuf, + process::exit, str::FromStr, time::{Duration, SystemTime}, }; -use taler_api::api_common::{crockford_base32_encode, Amount}; +use taler_api::api_common::{base32, Amount}; use taler_config::Config; use taler_log::log::{error, info, warn}; use url::Url; @@ -83,11 +84,11 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) if let Some(row) = &row { let id: i32 = row.get(0); let amount = taler_amount_to_btc_amount(&Amount::from_str(row.get(1))?)?; - let reserve_pub: &[u8] = row.get(2); + 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: reserve_pub.try_into()?, + wtid: wtid.try_into()?, url: exchange_base_url, }; let metadata = encode_info(&info); @@ -101,7 +102,7 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) &[&(TxStatus::Sent as i16), &tx_id.as_ref(), &id], )?; let amount = btc_amount_to_taler_amount(&amount.to_signed().unwrap()); - info!("send {} {} in {}", addr, amount, tx_id); + info!(">> {} {} in {} to {}", amount, base32(&wtid), tx_id, addr); } Err(e) => { info!("sender: RPC - {}", e); @@ -139,7 +140,7 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) fail_point("Skip send_op_return", 0.2)?; match rpc.bounce(&bounced, &fee, &metadata) { Ok(it) => { - info!("bounce {} in {}", &bounced, &it); + info!("|| {} in {}", &bounced, &it); tx.execute( "UPDATE bounce SET txid = $1, status = $2 WHERE id = $3", &[&it.as_ref(), &(BounceStatus::Sent as i16), &id], @@ -150,7 +151,7 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) code: ErrorCode::RpcWalletInsufficientFunds | ErrorCode::RpcWalletError, msg, } => { - info!("ignore bounce {} because {}", &bounced, msg); + info!("|| (ignore) {} because {}", &bounced, msg); tx.execute( "UPDATE bounce SET status = $1 WHERE id = $2", &[&(BounceStatus::Ignored as i16), &id], @@ -166,7 +167,8 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) // TODO check if transactions are abandoned - let mut failed = false; + // Alway start with a sync work + let mut skip_notification = true; loop { let rpc = rpc.client(); let db = db.client(); @@ -176,8 +178,7 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) // Wait for the next notification { let mut ntf = db.notifications(); - // On failure retry without waiting for notifications - if !failed && ntf.is_empty() { + if !skip_notification && ntf.is_empty() { // Block until next notification ntf.blocking_iter().next()?; } @@ -205,9 +206,10 @@ fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectSql, config: &Config) })(); if let Err(e) = result { error!("worker: DB - {}", e); - failed = true; + // On failure retry without waiting for notifications + skip_notification = true; } else { - failed = false; + skip_notification = false; } } } @@ -223,7 +225,7 @@ fn sync_chain( let min_confirmations = config.confirmation; // Get a set of transactions ids to parse - let (txs, lastblock): (HashMap, BlockHash) = { + let (txs, removed, lastblock): (HashMap, HashSet, BlockHash) = { // Get all transactions made since this block let list = rpc.list_since_block(last_hash.as_ref(), min_confirmations, true)?; // Only keep ids and category @@ -232,9 +234,35 @@ fn sync_chain( .into_iter() .map(|tx| (tx.txid, (tx.category, tx.confirmations))) .collect(); - (txs, list.lastblock) + let removed = list + .removed + .into_iter() + .filter_map(|tx| (tx.category == Category::Receive).then(|| tx.txid)) + .collect(); + (txs, removed, list.lastblock) }; + // Check if a confirmed incoming transaction have been removed by a blockchain reorganisation + if !removed.is_empty() { + for id in removed { + if let Ok((full, key)) = rpc.get_tx_segwit_key(&id) { + // If the removed tx is not in confirmed the txs list and the tx is stored in the database hard error + if txs + .get(&id) + .map(|(_, confirmations)| *confirmations < min_confirmations as i32) + .unwrap_or(true) + && db + .query_opt("SELECT 1 FROM tx_in WHERE reserve_pub=$1", &[&key.as_ref()])? + .is_some() + { + let credit_addr = full.details[0].address.as_ref().unwrap(); + error!("Received transaction {} in {} from {} have been removed from the blockchain, bitcoin backing is compromised until the transaction reappear", base32(&key), id, credit_addr); + exit(1); + } + } + } + } + for (id, (category, confirmations)) in txs { match category { Category::Send => { @@ -244,7 +272,7 @@ fn sync_chain( match decode_info(&bytes) { Ok(info) => { match info { - Info::Transaction { wtid, url } => { + Info::Transaction { wtid, .. } => { let addr = full.details[0].address.as_ref().unwrap(); let amount = btc_amount_to_taler_amount(&full.amount); @@ -262,8 +290,11 @@ fn sync_chain( &[&(TxStatus::Sent as i16), &_id], )?; warn!( - "send (recoverd) {} {} in {}", - addr, amount, &id + ">> (recovered) {} {} in {} to {}", + amount, + base32(&wtid), + id, + addr ); } TxStatus::Sent => {} @@ -281,10 +312,11 @@ fn sync_chain( )?; if nb > 0 { warn!( - "onchain {} {} in tx {}", - crockford_base32_encode(&wtid), - &url, - id + ">> (onchain) {} {} in {} to {}", + amount, + base32(&wtid), + id, + addr ); } } @@ -303,7 +335,7 @@ fn sync_chain( "UPDATE bounce SET status=$1 where id=$2", &[&(BounceStatus::Sent as i16), &_id], )?; - warn!("recovered bounce {} in {}", &bounced, &id); + warn!("|| (recovered) {} in {}", &bounced, &id); } BounceStatus::Ignored => error!("watcher: ignored bounce {} found in chain at {}", bounced, id), BounceStatus::Sent => {} @@ -314,7 +346,7 @@ fn sync_chain( &[&bounced.as_ref(), &id.as_ref(), &(BounceStatus::Sent as i16)], )?; if nb > 0 { - warn!("onchain bounce {} in {}", &bounced, &id); + warn!("|| (onchain) {} in {}", &bounced, &id); } } } @@ -342,8 +374,11 @@ fn sync_chain( ])?; if nb > 0 { info!( - "receive {} << {} {} in {}", - &debit_addr, &credit_addr, &amount, &id + "<< {} {} in {} from {}", + amount, + base32(&reserve_pub), + id, + debit_addr ); } } @@ -433,7 +468,6 @@ fn main() { let db_listener = AutoReconnectSql::new(&config.db_url, Duration::from_secs(5)); let db_worker = AutoReconnectSql::new(&config.db_url, Duration::from_secs(5)); - let join = std::thread::spawn(move || block_listener(rpc_listener, db_listener)); + std::thread::spawn(move || block_listener(rpc_listener, db_listener)); worker(rpc_worker, db_worker, config); - join.join().unwrap(); } diff --git a/makefile b/makefile index df745a4..1434a14 100644 --- a/makefile +++ b/makefile @@ -7,4 +7,5 @@ test: script/test_btc_wire.sh script/test_btc_reconnect.sh script/test_btc_fail.sh + script/test_btc_fork.sh script/test_btc_stress.sh \ No newline at end of file diff --git a/script/setup.sh b/script/setup.sh index ef3896a..080ed75 100644 --- a/script/setup.sh +++ b/script/setup.sh @@ -19,9 +19,11 @@ trap cleanup EXIT DIR=$(mktemp -d) BTC_DIR=$DIR/bitcoin +BTC_DIR2=$DIR/bitcoin2 DB_DIR=$DIR/db -mkdir -p $BTC_DIR -mkdir -p $DB_DIR +for dir in $BTC_DIR $BTC_DIR2 $DB_DIR; do + mkdir -p $dir +done # Load test.conf as bash variables function load_config() { @@ -29,6 +31,8 @@ function load_config() { BANK_ENDPOINT=http://127.0.0.1:$PORT/ } +# ----- Database ----- # + # Create new postgresql cluster and init database schema function setup_db() { pg_ctl init -D $DB_DIR &> /dev/null @@ -43,20 +47,47 @@ function reset_db() { psql $DB_URL < wire-gateway/db/schema.sql > /dev/null } -# Start a bitcoind regtest server in a temporary directory +# ----- Bitcoin node ----- # + +# Start a bitcoind regtest node function init_btc() { echo "regtest=1" > $BTC_DIR/bitcoin.conf echo "txindex=1" >> $BTC_DIR/bitcoin.conf echo "fallbackfee=0.00000001" >> $BTC_DIR/bitcoin.conf - BTC_CLI="bitcoin-cli -regtest -datadir=$BTC_DIR" - bitcoind -datadir=$BTC_DIR &> btc.log & + BTC_CLI="bitcoin-cli -datadir=$BTC_DIR" + bitcoind -datadir=$BTC_DIR -port=8345 &> btc.log & + BTC_PID="$!" $BTC_CLI -rpcwait getnetworkinfo > /dev/null } +# Start a second bitcoind regtest node connected to the first one +function init_btc2() { + echo "regtest=1" > $BTC_DIR2/bitcoin.conf + echo "txindex=1" >> $BTC_DIR2/bitcoin.conf + echo "fallbackfee=0.00000001" >> $BTC_DIR2/bitcoin.conf + echo "[regtest]" >> $BTC_DIR2/bitcoin.conf + echo "rpcport=18345" >> $BTC_DIR2/bitcoin.conf + BTC_CLI2="bitcoin-cli -datadir=$BTC_DIR2" + bitcoind -datadir=$BTC_DIR2 -port=8346 &> btc2.log & + $BTC_CLI2 -rpcwait getnetworkinfo > /dev/null + $BTC_CLI addnode 127.0.0.1:8346 onetry +} + +# Disconnect the two nodes +function btc2_deco() { + $BTC_CLI disconnectnode 127.0.0.1:8346 +} + +# Create a fork on the second node and reconnect the two node +function btc2_fork() { + $BTC_CLI2 generatetoaddress ${1:-50} $RESERVE > /dev/null + $BTC_CLI addnode 127.0.0.1:8346 onetry + sleep 1 +} + # Start a bitcoind regest server in a previously created temporary directory and load wallets function restart_btc() { - BTC_CLI="bitcoin-cli -regtest -datadir=$BTC_DIR" - bitcoind -datadir=$BTC_DIR -fallbackfee=0.00000001 &>> btc.log & + bitcoind -datadir=$BTC_DIR &>> btc.log & $BTC_CLI -rpcwait getnetworkinfo > /dev/null for wallet in wire client reserve; do $BTC_CLI loadwallet $wallet > /dev/null @@ -76,6 +107,11 @@ function setup_btc() { mine_btc } +function stop_btc() { + kill $BTC_PID + wait $BTC_PID +} + # Mine blocks function mine_btc() { $BTC_CLI generatetoaddress "${1:-1}" $RESERVE > /dev/null @@ -105,16 +141,20 @@ function check_balance() { fi } +# ----- btc-wire ----- # + # Start btc_wire function btc_wire() { cargo build --bin btc-wire --release &> /dev/null target/release/btc-wire $BTC_DIR &> btc_wire.log & + WIRE_PID="$!" } # Start btc_wire with random failures function fail_btc_wire() { cargo build --bin btc-wire --release --features fail &> /dev/null target/release/btc-wire $BTC_DIR &> btc_wire.log & + WIRE_PID="$!" } # Start multiple btc_wire in parallel @@ -124,6 +164,8 @@ function stressed_btc_wire() { target/release/btc-wire $BTC_DIR &> btc_wire1.log & } +# ----- Gateway ------ # + # Start wire_gateway in test mode function gateway() { cargo build --bin wire-gateway --release --features test &> /dev/null diff --git a/script/test_btc_fail.sh b/script/test_btc_fail.sh index 849a525..ee7e23b 100644 --- a/script/test_btc_fail.sh +++ b/script/test_btc_fail.sh @@ -13,7 +13,7 @@ echo "Start database" setup_db echo "Start bitcoin node" init_btc -echo "Start bitcoin regtest" +echo "Setup bitcoin" setup_btc echo "Start failing btc-wire" fail_btc_wire @@ -73,6 +73,7 @@ for n in `$SEQ`; do $BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.000$n > /dev/null mine_btc done +next_btc sleep 20 echo " OK" diff --git a/script/test_btc_fork.sh b/script/test_btc_fork.sh new file mode 100644 index 0000000..1bfc8e8 --- /dev/null +++ b/script/test_btc_fork.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +## Test btc_wire correctness when a blockchain reorganisation occurs + +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 "Setup bitcoin" +setup_btc +echo "Start second bitcoin node" +init_btc2 +echo "Start btc-wire" +btc_wire +echo "Start gateway" +gateway +echo "" + +# Check btc-wire is running +function check_up() { + if [ `ps -p $WIRE_PID | grep -c $WIRE_PID` == 0 ]; then + echo "btc_wire with pid $WIRE_PID should be up" + ps -p $WIRE_PID + exit 1 + fi +} + +# Check btc-wire is not running +function check_down() { + if [ `ps -p $WIRE_PID | grep -c $WIRE_PID` != 0 ]; then + echo "btc_wire with pid $WIRE_PID should be down" + ps -p $WIRE_PID + exit 1 + fi +} + +SEQ="seq 10 20" + +echo "----- Handle reorg incoming transactions -----" + +echo "Loose second bitcoin node" +btc2_deco + +echo -n "Gen incoming transactions:" +for n in `$SEQ`; do + btc-wire-cli -d $BTC_DIR transfer 0.000$n + mine_btc # Mine transactions +done +next_btc # Trigger btc_wire +check_delta "incoming?delta=-100" "$SEQ" "0.000" +check_balance 9.99826299 0.00165000 +echo " OK" + +echo -n "Perform fork and check btc-wire hard error:" +check_up +btc2_fork +check_balance 9.99826299 0.00000000 +check_down +echo " OK" + +echo -n "Check btc-wire hard error on restart:" +btc_wire +sleep 1 +check_down +echo " OK" + +echo -n "Recover orphaned transactions:" +next_btc +check_balance 9.99826299 0.00165000 +echo " OK" + +echo -n "Check btc-wire heal on restart:" +btc_wire +sleep 1 +check_up +echo " OK" + +echo "----- Handle reorg outgoing transactions -----" + +echo "Loose second bitcoin node" +btc2_deco + +echo -n "Gen outgoing transactions:" +for n in `$SEQ`; do + taler-exchange-wire-gateway-client \ + -b $BANK_ENDPOINT \ + -C payto://bitcoin/$CLIENT \ + -a BTC:0.0000$n > /dev/null +done +sleep 1 +mine_btc # Mine transactions +check_delta "outgoing?delta=-100" "$SEQ" +check_balance 9.99842799 0.00146311 +echo " OK" + +echo -n "Perform fork and check btc-wire still up:" +check_up +btc2_fork +check_balance 9.99826299 0.00146311 +check_up +echo " OK" + +echo -n "Recover orphaned transactions:" +next_btc +check_balance 9.99842799 0.00146311 +echo " OK" + +echo "----- Handle reorg bounce -----" + +echo -n "Clear wire wallet:" +$BTC_CLI -rpcwallet=wire sendtoaddress $CLIENT `$BTC_CLI -rpcwallet=wire getbalance` "" "" true > /dev/null +mine_btc +echo " OK" + +echo "Loose second bitcoin node" +btc2_deco + +echo -n "Generate bounce:" +for n in `$SEQ`; do + $BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.000$n > /dev/null + mine_btc +done +next_btc +sleep 1 +check_balance "*" 0.00011000 +echo " OK" + +echo -n "Perform fork and check btc-wire still up:" +check_up +btc2_fork +check_balance "*" 0.00000000 +check_up +echo " OK" + +echo -n "Recover orphaned transactions:" +next_btc +check_balance "*" 0.00011000 +echo " OK" + +echo "All tests passed" \ No newline at end of file diff --git a/script/test_btc_reconnect.sh b/script/test_btc_reconnect.sh index 3ab9292..32088b8 100644 --- a/script/test_btc_reconnect.sh +++ b/script/test_btc_reconnect.sh @@ -13,7 +13,7 @@ echo "Start database" setup_db echo "Start bitcoin node" init_btc -echo "Start bitcoin regtest" +echo "Setup bitcoin" setup_btc echo "Start btc-wire" btc_wire @@ -40,9 +40,7 @@ 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 +stop_btc 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" diff --git a/script/test_btc_stress.sh b/script/test_btc_stress.sh index 91f8f8b..10c7021 100644 --- a/script/test_btc_stress.sh +++ b/script/test_btc_stress.sh @@ -13,7 +13,7 @@ echo "Start database" setup_db echo "Start bitcoin node" init_btc -echo "Start bitcoin regtest" +echo "Setup bitcoin" setup_btc echo "Start btc-wire stressed" stressed_btc_wire @@ -97,7 +97,10 @@ for n in `$SEQ`; do $BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.000$n > /dev/null mine_btc done -sleep 20 +next_btc +sleep 10 +mine_btc +sleep 10 echo " OK" echo -n "Check balance:" diff --git a/script/test_btc_wire.sh b/script/test_btc_wire.sh index 3b48bae..6559bac 100644 --- a/script/test_btc_wire.sh +++ b/script/test_btc_wire.sh @@ -13,7 +13,7 @@ echo "Start database" setup_db echo "Start bitcoin node" init_btc -echo "Start bitcoin regtest" +echo "Setup bitcoin" setup_btc echo "Start btc-wire" btc_wire @@ -21,37 +21,56 @@ echo "Start gateway" gateway echo "" -echo "---- Receive -----" +SEQ="seq 10 20" + +echo "----- Receive -----" echo -n "Making wire transfer to exchange:" -btc-wire-cli -d $BTC_DIR transfer 0.00004 -next_btc -check_balance 9.99995209 0.00004000 +for n in `$SEQ`; do + btc-wire-cli -d $BTC_DIR transfer 0.000$n + mine_btc # Mine transactions +done +next_btc # Trigger btc_wire +check_balance 9.99826299 0.00165000 echo " OK" echo -n "Requesting exchange incoming transaction list:" -taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.00004 > /dev/null +check_delta "incoming?delta=-100" "$SEQ" "0.000" echo " OK" -echo "---- Bounce-----" -$BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.00042 -next_btc -check_balance 9.99993883 0.00005000 - -echo "---- Send -----" +echo "----- Send -----" 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 0.3 -mine_btc -check_balance 9.99995883 0.00002801 +for n in `$SEQ`; do + taler-exchange-wire-gateway-client \ + -b $BANK_ENDPOINT \ + -C payto://bitcoin/$CLIENT \ + -a BTC:0.0000$n > /dev/null +done +sleep 1 +mine_btc # Mine transactions +check_balance 9.99842799 0.00146311 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 +check_delta "outgoing?delta=-100" "$SEQ" +echo " OK" + +echo "----- Bounce -----" + +echo -n "Clear wire wallet:" +$BTC_CLI -rpcwallet=wire sendtoaddress $CLIENT `$BTC_CLI -rpcwallet=wire getbalance` "" "" true > /dev/null +mine_btc +echo " OK" + +echo -n "Bounce:" +for n in `$SEQ`; do + $BTC_CLI -rpcwallet=client sendtoaddress $WIRE 0.000$n > /dev/null + mine_btc +done +next_btc +sleep 1 +check_balance "*" 0.00011000 echo " OK" echo "All tests passed" \ No newline at end of file diff --git a/taler-api/src/api_common.rs b/taler-api/src/api_common.rs index 778e884..ab635ec 100644 --- a/taler-api/src/api_common.rs +++ b/taler-api/src/api_common.rs @@ -296,13 +296,13 @@ impl FromStr for Base32 { } } -pub fn crockford_base32_encode(bytes: &[u8]) -> String { +pub fn base32(bytes: &[u8]) -> String { base32::encode(base32::Alphabet::Crockford, bytes) } impl Display for Base32 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&crockford_base32_encode(&self.0)) + f.write_str(&base32(&self.0)) } } diff --git a/test.conf b/test.conf index 420edde..c0b88f0 100644 --- a/test.conf +++ b/test.conf @@ -6,7 +6,7 @@ DB_URL = postgres://localhost:5454/postgres?user=postgres&password=passwor PORT = 8060 UNIXPATH = TODO PAYTO = payto://bitcoin/bcrt1qgkgxkjj27g3f7s87mcvjjsghay7gh34cx39prj -CONFIRMATION = 1 +CONFIRMATION = 3 BTC_WALLET = wire BTC_DATA_DIR = ~/.bitcoin BOUNCE_FEE = 1000 \ No newline at end of file -- cgit v1.2.3