From 9b7b44ceba81390bfabc06c7f9ce55e01cb6472a Mon Sep 17 00:00:00 2001 From: rishflab Date: Fri, 11 Dec 2020 17:19:46 +1100 Subject: [PATCH] Remove old refund test --- Cargo.lock | 58 +------ xmr-btc/Cargo.toml | 10 -- xmr-btc/tests/e2e.rs | 98 ------------ xmr-btc/tests/harness/mod.rs | 202 ------------------------ xmr-btc/tests/harness/node.rs | 92 ----------- xmr-btc/tests/harness/transport.rs | 45 ------ xmr-btc/tests/harness/wallet/bitcoin.rs | 170 -------------------- xmr-btc/tests/harness/wallet/mod.rs | 2 - xmr-btc/tests/harness/wallet/monero.rs | 126 --------------- 9 files changed, 2 insertions(+), 801 deletions(-) delete mode 100644 xmr-btc/tests/e2e.rs delete mode 100644 xmr-btc/tests/harness/mod.rs delete mode 100644 xmr-btc/tests/harness/node.rs delete mode 100644 xmr-btc/tests/harness/transport.rs delete mode 100644 xmr-btc/tests/harness/wallet/bitcoin.rs delete mode 100644 xmr-btc/tests/harness/wallet/mod.rs delete mode 100644 xmr-btc/tests/harness/wallet/monero.rs diff --git a/Cargo.lock b/Cargo.lock index 363e9b51..c782210a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -500,19 +500,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time 0.1.44", - "winapi 0.3.9", -] - [[package]] name = "clap" version = "2.33.3" @@ -1247,7 +1234,7 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -3427,7 +3414,7 @@ dependencies = [ "structopt", "tempfile", "testcontainers", - "time 0.2.23", + "time", "tokio", "torut", "tracing", @@ -3565,17 +3552,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - [[package]] name = "time" version = "0.2.23" @@ -3789,16 +3765,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-serde" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" -dependencies = [ - "serde", - "tracing-core", -] - [[package]] name = "tracing-subscriber" version = "0.2.15" @@ -3806,19 +3772,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401" dependencies = [ "ansi_term 0.12.1", - "chrono", "lazy_static", "matchers", "regex", - "serde", - "serde_json", "sharded-slab", - "smallvec", "thread_local", "tracing", "tracing-core", - "tracing-log", - "tracing-serde", ] [[package]] @@ -3998,12 +3958,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasm-bindgen" version = "0.2.68" @@ -4176,10 +4130,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "backoff", - "base64 0.12.3", "bitcoin", - "bitcoin-harness", "conquer-once", "cross-curve-dleq", "curve25519-dalek 2.1.0", @@ -4189,19 +4140,14 @@ dependencies = [ "genawaiter", "miniscript", "monero", - "monero-harness", "rand 0.7.3", - "reqwest", "rust_decimal", "serde", "serde_cbor", "sha2 0.9.2", - "tempfile", - "testcontainers", "thiserror", "tokio", "tracing", - "tracing-subscriber", ] [[package]] diff --git a/xmr-btc/Cargo.toml b/xmr-btc/Cargo.toml index bfaf5f9e..57e134b5 100644 --- a/xmr-btc/Cargo.toml +++ b/xmr-btc/Cargo.toml @@ -28,14 +28,4 @@ tokio = { version = "0.2", default-features = false, features = ["time"] } tracing = "0.1" [dev-dependencies] -backoff = { version = "0.2", features = ["tokio"] } -base64 = "0.12" -bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs", rev = "864b55fcba2e770105f135781dd2e3002c503d12" } -futures = "0.3" -monero-harness = { path = "../monero-harness" } -reqwest = { version = "0.10", default-features = false } serde_cbor = "0.11" -tempfile = "3" -testcontainers = "0.11" -tracing = "0.1" -tracing-subscriber = "0.2" diff --git a/xmr-btc/tests/e2e.rs b/xmr-btc/tests/e2e.rs deleted file mode 100644 index 6ca819d0..00000000 --- a/xmr-btc/tests/e2e.rs +++ /dev/null @@ -1,98 +0,0 @@ -pub mod harness; - -mod tests { - use crate::{ - harness, - harness::{ - init_bitcoind, init_test, - node::{run_alice_until, run_bob_until}, - }, - }; - use futures::future; - use monero_harness::Monero; - use rand::rngs::OsRng; - use std::convert::TryInto; - use testcontainers::clients::Cli; - use xmr_btc::{ - alice, - bitcoin::{Amount, TX_FEE}, - bob, - }; - - #[tokio::test] - async fn both_refund() { - let cli = Cli::default(); - let (monero, _container) = Monero::new(&cli, Some("br".to_string()), vec![ - "alice".to_string(), - "bob".to_string(), - ]) - .await - .unwrap(); - let bitcoind = init_bitcoind(&cli).await; - - let ( - alice_state0, - bob_state0, - mut alice_node, - mut bob_node, - initial_balances, - swap_amounts, - ) = init_test(&monero, &bitcoind, None, None).await; - - let (alice_state, bob_state) = future::try_join( - run_alice_until( - &mut alice_node, - alice_state0.into(), - harness::alice::is_state5, - &mut OsRng, - ), - run_bob_until( - &mut bob_node, - bob_state0.into(), - harness::bob::is_state3, - &mut OsRng, - ), - ) - .await - .unwrap(); - - let alice_state5: alice::State5 = alice_state.try_into().unwrap(); - let bob_state3: bob::State3 = bob_state.try_into().unwrap(); - - bob_state3 - .refund_btc(&bob_node.bitcoin_wallet) - .await - .unwrap(); - alice_state5 - .refund_xmr(&alice_node.bitcoin_wallet, &alice_node.monero_wallet) - .await - .unwrap(); - - let alice_final_btc_balance = alice_node.bitcoin_wallet.balance().await.unwrap(); - let bob_final_btc_balance = bob_node.bitcoin_wallet.balance().await.unwrap(); - - // lock_tx_bitcoin_fee is determined by the wallet, it is not necessarily equal - // to TX_FEE - let lock_tx_bitcoin_fee = bob_node - .bitcoin_wallet - .transaction_fee(bob_state3.tx_lock_id()) - .await - .unwrap(); - - monero.wallet("alice").unwrap().refresh().await.unwrap(); - let alice_final_xmr_balance = alice_node.monero_wallet.get_balance().await.unwrap(); - let bob_final_xmr_balance = bob_node.monero_wallet.get_balance().await.unwrap(); - - assert_eq!(alice_final_btc_balance, initial_balances.alice_btc); - assert_eq!( - bob_final_btc_balance, - // The 2 * TX_FEE corresponds to tx_refund and tx_cancel. - initial_balances.bob_btc - Amount::from_sat(2 * TX_FEE) - lock_tx_bitcoin_fee - ); - - // Because we create a new wallet when claiming Monero, we can only assert on - // this new wallet owning all of `xmr_amount` after refund - assert_eq!(alice_final_xmr_balance, swap_amounts.xmr); - assert_eq!(bob_final_xmr_balance, initial_balances.bob_xmr); - } -} diff --git a/xmr-btc/tests/harness/mod.rs b/xmr-btc/tests/harness/mod.rs deleted file mode 100644 index c1efa323..00000000 --- a/xmr-btc/tests/harness/mod.rs +++ /dev/null @@ -1,202 +0,0 @@ -pub mod node; -pub mod transport; -pub mod wallet; - -pub mod bob { - use xmr_btc::bob::State; - - pub fn is_state2(state: &State) -> bool { - matches!(state, State::State2 { .. }) - } - - // TODO: use macro or generics - pub fn is_state5(state: &State) -> bool { - matches!(state, State::State5 { .. }) - } - - // TODO: use macro or generics - pub fn is_state3(state: &State) -> bool { - matches!(state, State::State3 { .. }) - } -} - -pub mod alice { - use xmr_btc::alice::State; - - pub fn is_state3(state: &State) -> bool { - matches!(state, State::State3 { .. }) - } - - // TODO: use macro or generics - pub fn is_state4(state: &State) -> bool { - matches!(state, State::State4 { .. }) - } - - // TODO: use macro or generics - pub fn is_state5(state: &State) -> bool { - matches!(state, State::State5 { .. }) - } - - // TODO: use macro or generics - pub fn is_state6(state: &State) -> bool { - matches!(state, State::State6 { .. }) - } -} - -use bitcoin_harness::Bitcoind; -use monero_harness::Monero; -use node::{AliceNode, BobNode}; -use rand::rngs::OsRng; -use testcontainers::clients::Cli; -use tokio::sync::{ - mpsc, - mpsc::{Receiver, Sender}, -}; -use transport::Transport; -use xmr_btc::{bitcoin, monero}; - -const TEN_XMR: u64 = 10_000_000_000_000; -const RELATIVE_REFUND_TIMELOCK: u32 = 1; -const RELATIVE_PUNISH_TIMELOCK: u32 = 1; -pub const ALICE_TEST_DB_FOLDER: &str = "../target/e2e-test-alice-recover"; -pub const BOB_TEST_DB_FOLDER: &str = "../target/e2e-test-bob-recover"; - -pub async fn init_bitcoind(tc_client: &Cli) -> Bitcoind<'_> { - let bitcoind = Bitcoind::new(tc_client, "0.19.1").expect("failed to create bitcoind"); - let _ = bitcoind.init(5).await; - - bitcoind -} - -pub struct InitialBalances { - pub alice_xmr: monero::Amount, - pub alice_btc: bitcoin::Amount, - pub bob_xmr: monero::Amount, - pub bob_btc: bitcoin::Amount, -} - -pub struct SwapAmounts { - pub xmr: monero::Amount, - pub btc: bitcoin::Amount, -} - -pub fn init_alice_and_bob_transports() -> ( - Transport, - Transport, -) { - let (a_sender, b_receiver): ( - Sender, - Receiver, - ) = mpsc::channel(5); - let (b_sender, a_receiver): ( - Sender, - Receiver, - ) = mpsc::channel(5); - - let a_transport = Transport { - sender: a_sender, - receiver: a_receiver, - }; - - let b_transport = Transport { - sender: b_sender, - receiver: b_receiver, - }; - - (a_transport, b_transport) -} - -pub async fn init_test( - monero: &Monero, - bitcoind: &Bitcoind<'_>, - refund_timelock: Option, - punish_timelock: Option, -) -> ( - xmr_btc::alice::State0, - xmr_btc::bob::State0, - AliceNode, - BobNode, - InitialBalances, - SwapAmounts, -) { - // must be bigger than our hardcoded fee of 10_000 - let btc_amount = bitcoin::Amount::from_sat(10_000_000); - let xmr_amount = monero::Amount::from_piconero(1_000_000_000_000); - - let swap_amounts = SwapAmounts { - xmr: xmr_amount, - btc: btc_amount, - }; - - let fund_alice = TEN_XMR; - let fund_bob = 0; - monero - .init(vec![("alice", fund_alice), ("bob", fund_bob)]) - .await - .unwrap(); - - let alice_monero_wallet = wallet::monero::Wallet(monero.wallet("alice").unwrap().client()); - let bob_monero_wallet = wallet::monero::Wallet(monero.wallet("bob").unwrap().client()); - - let alice_btc_wallet = wallet::bitcoin::Wallet::new("alice", &bitcoind.node_url) - .await - .unwrap(); - let bob_btc_wallet = wallet::bitcoin::make_wallet("bob", &bitcoind, btc_amount) - .await - .unwrap(); - - let (alice_transport, bob_transport) = init_alice_and_bob_transports(); - let alice = AliceNode::new(alice_transport, alice_btc_wallet, alice_monero_wallet); - - let bob = BobNode::new(bob_transport, bob_btc_wallet, bob_monero_wallet); - - let alice_initial_btc_balance = alice.bitcoin_wallet.balance().await.unwrap(); - let bob_initial_btc_balance = bob.bitcoin_wallet.balance().await.unwrap(); - - let alice_initial_xmr_balance = alice.monero_wallet.get_balance().await.unwrap(); - let bob_initial_xmr_balance = bob.monero_wallet.get_balance().await.unwrap(); - - let redeem_address = alice.bitcoin_wallet.new_address().await.unwrap(); - let punish_address = redeem_address.clone(); - let refund_address = bob.bitcoin_wallet.new_address().await.unwrap(); - - let alice_state0 = { - let a = bitcoin::SecretKey::new_random(&mut OsRng); - let s_a = cross_curve_dleq::Scalar::random(&mut OsRng); - let v_a = monero::PrivateViewKey::new_random(&mut OsRng); - - xmr_btc::alice::State0::new( - a, - s_a, - v_a, - btc_amount, - xmr_amount, - refund_timelock.unwrap_or(RELATIVE_REFUND_TIMELOCK), - punish_timelock.unwrap_or(RELATIVE_PUNISH_TIMELOCK), - redeem_address.clone(), - punish_address.clone(), - ) - }; - let bob_state0 = xmr_btc::bob::State0::new( - &mut OsRng, - btc_amount, - xmr_amount, - refund_timelock.unwrap_or(RELATIVE_REFUND_TIMELOCK), - punish_timelock.unwrap_or(RELATIVE_PUNISH_TIMELOCK), - refund_address, - ); - let initial_balances = InitialBalances { - alice_xmr: alice_initial_xmr_balance, - alice_btc: alice_initial_btc_balance, - bob_xmr: bob_initial_xmr_balance, - bob_btc: bob_initial_btc_balance, - }; - ( - alice_state0, - bob_state0, - alice, - bob, - initial_balances, - swap_amounts, - ) -} diff --git a/xmr-btc/tests/harness/node.rs b/xmr-btc/tests/harness/node.rs deleted file mode 100644 index 7b4bf207..00000000 --- a/xmr-btc/tests/harness/node.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::harness::{transport::Transport, wallet}; -use anyhow::Result; -use rand::{CryptoRng, RngCore}; -use xmr_btc::{alice, bob}; - -// TODO: merge this with bob node -// This struct is responsible for I/O -pub struct AliceNode { - transport: Transport, - pub bitcoin_wallet: wallet::bitcoin::Wallet, - pub monero_wallet: wallet::monero::Wallet, -} - -impl AliceNode { - pub fn new( - transport: Transport, - bitcoin_wallet: wallet::bitcoin::Wallet, - monero_wallet: wallet::monero::Wallet, - ) -> AliceNode { - Self { - transport, - bitcoin_wallet, - monero_wallet, - } - } -} - -pub async fn run_alice_until( - alice: &mut AliceNode, - initial_state: alice::State, - is_state: fn(&alice::State) -> bool, - rng: &mut R, -) -> Result { - let mut result = initial_state; - loop { - result = alice::next_state( - &alice.bitcoin_wallet, - &alice.monero_wallet, - &mut alice.transport, - result, - rng, - ) - .await?; - if is_state(&result) { - return Ok(result); - } - } -} - -// TODO: merge this with alice node -// This struct is responsible for I/O -pub struct BobNode { - transport: Transport, - pub bitcoin_wallet: wallet::bitcoin::Wallet, - pub monero_wallet: wallet::monero::Wallet, -} - -impl BobNode { - pub fn new( - transport: Transport, - bitcoin_wallet: wallet::bitcoin::Wallet, - monero_wallet: wallet::monero::Wallet, - ) -> BobNode { - Self { - transport, - bitcoin_wallet, - monero_wallet, - } - } -} - -pub async fn run_bob_until( - bob: &mut BobNode, - initial_state: bob::State, - is_state: fn(&bob::State) -> bool, - rng: &mut R, -) -> Result { - let mut result = initial_state; - loop { - result = bob::next_state( - &bob.bitcoin_wallet, - &bob.monero_wallet, - &mut bob.transport, - result, - rng, - ) - .await?; - if is_state(&result) { - return Ok(result); - } - } -} diff --git a/xmr-btc/tests/harness/transport.rs b/xmr-btc/tests/harness/transport.rs deleted file mode 100644 index 1c912b02..00000000 --- a/xmr-btc/tests/harness/transport.rs +++ /dev/null @@ -1,45 +0,0 @@ -use anyhow::{anyhow, Result}; -use async_trait::async_trait; -use tokio::{ - stream::StreamExt, - sync::mpsc::{Receiver, Sender}, -}; -use xmr_btc::transport::{ReceiveMessage, SendMessage}; - -#[derive(Debug)] -pub struct Transport { - pub sender: Sender, - pub receiver: Receiver, -} - -#[async_trait] -impl SendMessage for Transport -where - SendMsg: Send + Sync, - RecvMsg: std::marker::Send, -{ - async fn send_message(&mut self, message: SendMsg) -> Result<()> { - let _ = self - .sender - .send(message) - .await - .map_err(|_| anyhow!("failed to send message"))?; - Ok(()) - } -} - -#[async_trait] -impl ReceiveMessage for Transport -where - SendMsg: std::marker::Send, - RecvMsg: Send + Sync, -{ - async fn receive_message(&mut self) -> Result { - let message = self - .receiver - .next() - .await - .ok_or_else(|| anyhow!("failed to receive message"))?; - Ok(message) - } -} diff --git a/xmr-btc/tests/harness/wallet/bitcoin.rs b/xmr-btc/tests/harness/wallet/bitcoin.rs deleted file mode 100644 index 897322c5..00000000 --- a/xmr-btc/tests/harness/wallet/bitcoin.rs +++ /dev/null @@ -1,170 +0,0 @@ -use anyhow::{Context, Result}; -use async_trait::async_trait; -use backoff::{backoff::Constant as ConstantBackoff, future::FutureOperation as _}; -use bitcoin::{util::psbt::PartiallySignedTransaction, Address, Amount, Transaction, Txid}; -use bitcoin_harness::{bitcoind_rpc::PsbtBase64, Bitcoind, BitcoindRpcApi}; -use reqwest::Url; -use std::time::Duration; -use tokio::time; -use xmr_btc::bitcoin::{ - BlockHeight, BroadcastSignedTransaction, BuildTxLockPsbt, Network, SignTxLock, - TransactionBlockHeight, TxLock, WatchForRawTransaction, -}; - -#[derive(Debug)] -pub struct Wallet(pub bitcoin_harness::Wallet); - -impl Wallet { - pub async fn new(name: &str, url: &Url) -> Result { - let wallet = bitcoin_harness::Wallet::new(name, url.clone()).await?; - - Ok(Self(wallet)) - } - - pub async fn balance(&self) -> Result { - let balance = self.0.balance().await?; - Ok(balance) - } - - pub async fn new_address(&self) -> Result
{ - self.0.new_address().await.map_err(Into::into) - } - - pub async fn transaction_fee(&self, txid: Txid) -> Result { - let fee = self - .0 - .get_wallet_transaction(txid) - .await - .map(|res| { - res.fee.map(|signed_amount| { - signed_amount - .abs() - .to_unsigned() - .expect("Absolute value is always positive") - }) - })? - .context("Rpc response did not contain a fee")?; - - Ok(fee) - } -} - -pub async fn make_wallet( - name: &str, - bitcoind: &Bitcoind<'_>, - fund_amount: Amount, -) -> Result { - let wallet = Wallet::new(name, &bitcoind.node_url).await?; - let buffer = Amount::from_btc(1.0).unwrap(); - let amount = fund_amount + buffer; - - let address = wallet.0.new_address().await.unwrap(); - - bitcoind.mint(address, amount).await.unwrap(); - - Ok(wallet) -} - -#[async_trait] -impl BuildTxLockPsbt for Wallet { - async fn build_tx_lock_psbt( - &self, - output_address: Address, - output_amount: Amount, - ) -> Result { - let psbt = self.0.fund_psbt(output_address, output_amount).await?; - let as_hex = base64::decode(psbt)?; - - let psbt = bitcoin::consensus::deserialize(&as_hex)?; - - Ok(psbt) - } -} - -#[async_trait] -impl SignTxLock for Wallet { - async fn sign_tx_lock(&self, tx_lock: TxLock) -> Result { - let psbt = PartiallySignedTransaction::from(tx_lock); - - let psbt = bitcoin::consensus::serialize(&psbt); - let as_base64 = base64::encode(psbt); - - let psbt = self.0.wallet_process_psbt(PsbtBase64(as_base64)).await?; - let PsbtBase64(signed_psbt) = PsbtBase64::from(psbt); - - let as_hex = base64::decode(signed_psbt)?; - let psbt: PartiallySignedTransaction = bitcoin::consensus::deserialize(&as_hex)?; - - let tx = psbt.extract_tx(); - - Ok(tx) - } -} - -#[async_trait] -impl BroadcastSignedTransaction for Wallet { - async fn broadcast_signed_transaction(&self, transaction: Transaction) -> Result { - let txid = self.0.send_raw_transaction(transaction).await?; - - // TODO: Instead of guessing how long it will take for the transaction to be - // mined we should ask bitcoind for the number of confirmations on `txid` - - // give time for transaction to be mined - time::delay_for(Duration::from_millis(1100)).await; - - Ok(txid) - } -} - -#[async_trait] -impl WatchForRawTransaction for Wallet { - async fn watch_for_raw_transaction(&self, txid: Txid) -> Transaction { - (|| async { Ok(self.0.get_raw_transaction(txid).await?) }) - .retry(ConstantBackoff::new(Duration::from_secs(1))) - .await - .expect("transient errors to be retried") - } -} - -#[async_trait] -impl BlockHeight for Wallet { - async fn block_height(&self) -> u32 { - (|| async { Ok(self.0.client.getblockcount().await?) }) - .retry(ConstantBackoff::new(Duration::from_secs(1))) - .await - .expect("transient errors to be retried") - } -} - -#[async_trait] -impl TransactionBlockHeight for Wallet { - async fn transaction_block_height(&self, txid: Txid) -> u32 { - #[derive(Debug)] - enum Error { - Io, - NotYetMined, - } - - (|| async { - let block_height = self - .0 - .transaction_block_height(txid) - .await - .map_err(|_| backoff::Error::Transient(Error::Io))?; - - let block_height = - block_height.ok_or_else(|| backoff::Error::Transient(Error::NotYetMined))?; - - Result::<_, backoff::Error>::Ok(block_height) - }) - .retry(ConstantBackoff::new(Duration::from_secs(1))) - .await - .expect("transient errors to be retried") - } -} - -impl Network for Wallet { - fn get_network(&self) -> bitcoin::Network { - bitcoin::Network::Regtest - } -} diff --git a/xmr-btc/tests/harness/wallet/mod.rs b/xmr-btc/tests/harness/wallet/mod.rs deleted file mode 100644 index c2b89100..00000000 --- a/xmr-btc/tests/harness/wallet/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod bitcoin; -pub mod monero; diff --git a/xmr-btc/tests/harness/wallet/monero.rs b/xmr-btc/tests/harness/wallet/monero.rs deleted file mode 100644 index fbfd4270..00000000 --- a/xmr-btc/tests/harness/wallet/monero.rs +++ /dev/null @@ -1,126 +0,0 @@ -use anyhow::Result; -use async_trait::async_trait; -use backoff::{backoff::Constant as ConstantBackoff, future::FutureOperation as _}; -use monero_harness::rpc::wallet; -use std::{str::FromStr, time::Duration}; -use xmr_btc::monero::{ - Address, Amount, CreateWalletForOutput, InsufficientFunds, Network, PrivateKey, PrivateViewKey, - PublicKey, PublicViewKey, Transfer, TransferProof, TxHash, WatchForTransfer, -}; - -pub struct Wallet(pub wallet::Client); - -impl Wallet { - /// Get the balance of the primary account. - pub async fn get_balance(&self) -> Result { - let amount = self.0.get_balance(0).await?; - - Ok(Amount::from_piconero(amount)) - } -} - -#[async_trait] -impl Transfer for Wallet { - async fn transfer( - &self, - public_spend_key: PublicKey, - public_view_key: PublicViewKey, - amount: Amount, - ) -> Result<(TransferProof, Amount)> { - let destination_address = - Address::standard(Network::Mainnet, public_spend_key, public_view_key.into()); - - let res = self - .0 - .transfer(0, amount.as_piconero(), &destination_address.to_string()) - .await?; - - let tx_hash = TxHash(res.tx_hash); - let tx_key = PrivateKey::from_str(&res.tx_key)?; - - let fee = Amount::from_piconero(res.fee); - - Ok((TransferProof::new(tx_hash, tx_key), fee)) - } -} - -#[async_trait] -impl CreateWalletForOutput for Wallet { - async fn create_and_load_wallet_for_output( - &self, - private_spend_key: PrivateKey, - private_view_key: PrivateViewKey, - ) -> Result<()> { - let public_spend_key = PublicKey::from_private_key(&private_spend_key); - let public_view_key = PublicKey::from_private_key(&private_view_key.into()); - - let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key); - - let _ = self - .0 - .generate_from_keys( - &address.to_string(), - &private_spend_key.to_string(), - &PrivateKey::from(private_view_key).to_string(), - ) - .await?; - - Ok(()) - } -} - -#[async_trait] -impl WatchForTransfer for Wallet { - async fn watch_for_transfer( - &self, - public_spend_key: PublicKey, - public_view_key: PublicViewKey, - transfer_proof: TransferProof, - expected_amount: Amount, - expected_confirmations: u32, - ) -> Result<(), InsufficientFunds> { - enum Error { - TxNotFound, - InsufficientConfirmations, - InsufficientFunds { expected: Amount, actual: Amount }, - } - - let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key.into()); - - let res = (|| async { - // NOTE: Currently, this is conflating IO errors with the transaction not being - // in the blockchain yet, or not having enough confirmations on it. All these - // errors warrant a retry, but the strategy should probably differ per case - let proof = self - .0 - .check_tx_key( - &String::from(transfer_proof.tx_hash()), - &transfer_proof.tx_key().to_string(), - &address.to_string(), - ) - .await - .map_err(|_| backoff::Error::Transient(Error::TxNotFound))?; - - if proof.received != expected_amount.as_piconero() { - return Err(backoff::Error::Permanent(Error::InsufficientFunds { - expected: expected_amount, - actual: Amount::from_piconero(proof.received), - })); - } - - if proof.confirmations < expected_confirmations { - return Err(backoff::Error::Transient(Error::InsufficientConfirmations)); - } - - Ok(proof) - }) - .retry(ConstantBackoff::new(Duration::from_secs(1))) - .await; - - if let Err(Error::InsufficientFunds { expected, actual }) = res { - return Err(InsufficientFunds { expected, actual }); - }; - - Ok(()) - } -}