depolymerization

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

commit b8b1200be9810a1e03f47e90c2d3f0ebb309ccd5
parent 13fbeae1712c636b74fbb0cdfd0e7bd3d8e51a63
Author: Antoine A <>
Date:   Fri, 10 Dec 2021 17:39:37 +0100

Improve btc-wire test

Diffstat:
Mbtc-wire/src/bin/btc-wire-cli.rs | 37++++++++++++++++++++++++++-----------
Mbtc-wire/src/main.rs | 18+++++++++++++-----
Mbtc-wire/src/rpc_utils.rs | 23++++++++++-------------
Mscript/test_btc_wire.sh | 54++++++++++++++++++++++++++++++++++++++----------------
4 files changed, 87 insertions(+), 45 deletions(-)

diff --git a/btc-wire/src/bin/btc-wire-cli.rs b/btc-wire/src/bin/btc-wire-cli.rs @@ -1,9 +1,11 @@ +use std::path::PathBuf; + use bitcoincore_rpc::{ bitcoin::{Address, Amount}, Client, RpcApi, }; use btc_wire::{ - rpc_utils::{common_rpc, data_dir_path, dirty_guess_network, wallet_rpc, Network}, + rpc_utils::{common_rpc, default_data_dir, dirty_guess_network, wallet_rpc, Network}, test::rand_key, ClientExtended, }; @@ -11,6 +13,9 @@ use btc_wire::{ #[derive(argh::FromArgs)] /// Bitcoin wire test client struct Args { + #[argh(option, short = 'd')] + /// specify data directory + datadir: Option<PathBuf>, #[argh(subcommand)] cmd: Cmd, } @@ -65,22 +70,29 @@ struct InitCmd {} struct ResetCmd {} struct App { + data_dir: PathBuf, network: Network, client: Client, } impl App { - pub fn start() -> Self { - let network = dirty_guess_network(); - let client = common_rpc(network).expect("Failed to connect to bitcoin core server"); - - Self { network, client } + pub fn start(data_dir: Option<PathBuf>) -> Self { + let data_dir = data_dir.unwrap_or(default_data_dir()); + let network = dirty_guess_network(&data_dir); + let client = + common_rpc(&data_dir, network).expect("Failed to connect to bitcoin core server"); + + Self { + data_dir, + network, + client, + } } pub fn auto_wallet(&self, name: &str) -> (Client, Address) { // Auto load self.client.load_wallet(name).ok(); - let wallet = wallet_rpc(self.network, name); + let wallet = wallet_rpc(&self.data_dir, self.network, name); let addr = wallet .get_new_address(None, None) .expect(&format!("Failed to get wallet address {}", name)); @@ -117,9 +129,12 @@ impl App { fn main() { let args: Args = argh::from_env(); match args.cmd { - Cmd::Init(_) => App::start().init(), + Cmd::Init(_) => App::start(args.datadir).init(), Cmd::Reset(_) => { - let path = data_dir_path().join(Network::RegTest.dir()); + let path = args + .datadir + .unwrap_or(default_data_dir()) + .join(Network::RegTest.dir()); if path.exists() { std::fs::remove_dir_all(path).unwrap(); } @@ -130,7 +145,7 @@ fn main() { to, amount, }) => { - let app = App::start(); + let app = App::start(args.datadir); let (client, _) = app.auto_wallet(&from); let (_, to) = app.auto_wallet(&to); client @@ -138,7 +153,7 @@ fn main() { .unwrap(); } Cmd::NextBlock(NextBlockCmd { to }) => { - let app = App::start(); + let app = App::start(args.datadir); app.next_block(&to); } } diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs @@ -4,7 +4,9 @@ use bitcoincore_rpc::{ Client as RPC, RpcApi, }; use btc_wire::{ - rpc_utils::{common_rpc, dirty_guess_network, sender_address, wallet_rpc, WIRE}, + rpc_utils::{ + common_rpc, default_data_dir, dirty_guess_network, sender_address, wallet_rpc, WIRE, + }, segwit::DecodeSegWitErr, ClientExtended, GetOpReturnErr, GetSegwitErr, }; @@ -12,6 +14,7 @@ use configparser::ini::Ini; use postgres::{fallible_iterator::FallibleIterator, Client, NoTls}; use std::{ collections::HashMap, + path::PathBuf, process::exit, str::FromStr, time::{Duration, SystemTime}, @@ -249,11 +252,16 @@ fn main() { let db_url = conf.get("main", "DB_URL").expect("Missing BD_URL"); // Guess network by trying to connect to a JSON RPC server - let network = dirty_guess_network(); - let rpc = common_rpc(network).unwrap(); + let data_dir = std::env::args() + .skip(1) + .next() + .map(|str| PathBuf::from_str(&str).unwrap()) + .unwrap_or(default_data_dir()); + let network = dirty_guess_network(&data_dir); + let rpc = common_rpc(&data_dir, network).unwrap(); rpc.load_wallet(&WIRE).ok(); - let rpc_watcher = wallet_rpc(network, "wire"); - let rpc_sender = wallet_rpc(network, "wire"); + let rpc_watcher = wallet_rpc(&data_dir, network, "wire"); + let rpc_sender = wallet_rpc(&data_dir, network, "wire"); let db_watcher = Client::connect(&db_url, NoTls).unwrap(); let db_sender = Client::connect(&db_url, NoTls).unwrap(); diff --git a/btc-wire/src/rpc_utils.rs b/btc-wire/src/rpc_utils.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, str::FromStr}; +use std::{path::{PathBuf, Path}, str::FromStr}; use bitcoincore_rpc::{ bitcoin::{Address, Amount, BlockHash, Txid}, @@ -39,7 +39,7 @@ pub fn rpc_url(network: Network) -> String { format!("https://127.0.0.1:{}", port) } -pub fn data_dir_path() -> PathBuf { +pub fn default_data_dir() -> PathBuf { // https://github.com/bitcoin/bitcoin/blob/master/doc/bitcoin-conf.md#:~:text=By%20default%2C%20the%20configuration%20file,file%3E%20option%20in%20the%20bitcoin. if cfg!(target_os = "windows") { PathBuf::from_str(&std::env::var("APPDATA").unwrap()) @@ -58,21 +58,18 @@ pub fn data_dir_path() -> PathBuf { } } -pub fn network_dir_path(network: Network) -> PathBuf { - data_dir_path().join(network.dir()) -} -pub fn common_rpc(network: Network) -> bitcoincore_rpc::Result<Client> { +pub fn common_rpc(data_dir: &Path, network: Network) -> bitcoincore_rpc::Result<Client> { Client::new( &rpc_url(network), - Auth::CookieFile(network_dir_path(network).join(".cookie")), + Auth::CookieFile(data_dir.join(network.dir()).join(".cookie")), ) } -pub fn wallet_rpc(network: Network, wallet: &str) -> Client { +pub fn wallet_rpc(data_dir: &Path, network: Network, wallet: &str) -> Client { Client::new( &format!("{}/wallet/{}", rpc_url(network), wallet), - Auth::CookieFile(network_dir_path(network).join(".cookie")), + Auth::CookieFile(data_dir.join(network.dir()).join(".cookie")), ) .expect(&format!("Failed to open wallet '{}' client", wallet)) } @@ -107,17 +104,17 @@ pub fn received_since( )) } -pub fn dirty_guess_network() -> Network { - let result_reg = common_rpc(Network::RegTest).and_then(|rpc| rpc.get_network_info()); +pub fn dirty_guess_network(data_dir: &Path) -> Network { + let result_reg = common_rpc(data_dir, Network::RegTest).and_then(|rpc| rpc.get_network_info()); if result_reg.is_ok() { return Network::RegTest; } - let result_test = common_rpc(Network::TestNet).and_then(|rpc| rpc.get_network_info()); + let result_test = common_rpc(data_dir, Network::TestNet).and_then(|rpc| rpc.get_network_info()); if result_test.is_ok() { return Network::TestNet; } - let result_main = common_rpc(Network::MainNet).and_then(|rpc| rpc.get_network_info()); + let result_main = common_rpc(data_dir, Network::MainNet).and_then(|rpc| rpc.get_network_info()); if result_main.is_ok() { return Network::MainNet; } diff --git a/script/test_btc_wire.sh b/script/test_btc_wire.sh @@ -2,11 +2,15 @@ set -eu +# Create temp file +TEMP_DIR=$(mktemp -d) + # Cleanup to run whenever we exit function cleanup() { for n in `jobs -p`; do kill $n 2> /dev/null || true done + rm -rf $TEMP_DIR 2> /dev/null wait } @@ -16,21 +20,43 @@ trap cleanup EXIT source <(grep = test.conf | sed 's/ *= */=/' | sed 's/=\(.*\)/="\1"/g1') BANK_ENDPOINT=http://127.0.0.1:$PORT/ +BTC_CLI="bitcoin-cli -regtest -datadir=$TEMP_DIR" echo "---- Setup -----" echo "Reset database" sudo -u postgres psql $DB_URL < wire-gateway/db/schema.sql > /dev/null -echo "Reset bitcoin regtest" -btc-wire-cli reset echo "Start bitcoin node" -bitcoind -regtest -fallbackfee=0.00001 > /dev/null & -bitcoin-cli -rpcwait getnetworkinfo > /dev/null +bitcoind -datadir=$TEMP_DIR -txindex -regtest -fallbackfee=0.00000001 &> /dev/null & +$BTC_CLI -rpcwait getnetworkinfo > /dev/null echo "Init bitcoin regtest" -btc-wire-cli init +for wallet in wire client reserve; do + $BTC_CLI createwallet $wallet > /dev/null +done +RESERVE=`$BTC_CLI -rpcwallet=reserve getnewaddress` +CLIENT=`$BTC_CLI -rpcwallet=client getnewaddress` +$BTC_CLI generatetoaddress 101 $RESERVE > /dev/null +$BTC_CLI -rpcwallet=reserve sendtoaddress $CLIENT 1 > /dev/null +$BTC_CLI generatetoaddress 1 $RESERVE > /dev/null +function check_balance() { + CLIENT_BALANCE=`$BTC_CLI -rpcwallet=client getbalance` + WIRE_BALANCE=`$BTC_CLI -rpcwallet=wire getbalance` + if [ "$CLIENT_BALANCE" != "$1" ] || [ "$WIRE_BALANCE" != "$2" ]; then + echo "expected: client $1 wire $2" + echo "got: client $CLIENT_BALANCE wire $WIRE_BALANCE" + exit 1 + fi +} +function next() { + # Mine one block + $BTC_CLI generatetoaddress 1 $RESERVE > /dev/null + # Wait for btc_wire to catch up + sleep 0.5 +} +check_balance 1.00000000 0.00000000 echo "Start btc-wire" cargo build --bin btc-wire &> /dev/null -target/debug/btc-wire &> /dev/null & +target/debug/btc-wire $TEMP_DIR &> /dev/null & echo "Start gateway" cargo build --bin wire-gateway --features test &> /dev/null target/debug/wire-gateway &> /dev/null & @@ -44,9 +70,9 @@ echo "" echo "---- Gateway API -----" echo -n "Making wire transfer to exchange:" -btc-wire-cli transfer 0.00004 -btc-wire-cli nblock -sleep 0.5 +btc-wire-cli -d $TEMP_DIR transfer 0.00004 +next +check_balance 0.99995209 0.00004000 echo " OK" echo -n "Requesting exchange incoming transaction list:" @@ -54,21 +80,17 @@ taler-exchange-wire-gateway-client -b $BANK_ENDPOINT -i | grep BTC:0.00004 > /de echo " OK" echo -n "Making wire transfer from exchange:" - -ADDRESS=`bitcoin-cli -rpcwallet=client getnewaddress` taler-exchange-wire-gateway-client \ -b $BANK_ENDPOINT \ - -C payto://bitcoin/$ADDRESS \ + -C payto://bitcoin/$CLIENT \ -a BTC:0.00002 > /dev/null -btc-wire-cli nblock -sleep 0.5 +next +check_balance 0.99995209 0.00001801 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 "All tests passed" \ No newline at end of file