xmr-btc-swap/monero-harness/tests/wallet.rs
Daniel Karzel c976358c37
Multiple swaps with the same peer
- Swap-id is exchanged during execution setup. CLI (Bob) sends the swap-id to be used in his first message.
- Transfer poof and encryption signature messages include the swap-id so it can be properly associated with the correct swap.
- ASB: Encryption signatures are associated with swaps by swap-id, not peer-id.
- ASB: Transfer proofs are still associated to peer-ids (because they have to be sent to the respective peer), but the ASB can buffer multiple
- CLI: Incoming transfer proofs are checked for matching swap-id. If a transfer proof with a different swap-id than the current executing swap is received it will be ignored. We can change this to saving into the database.

Includes concurrent swap tests with the same Bob.

- One test that pauses and starts an additional swap after the transfer proof was received. Results in both swaps being redeemed after resuming the first swap.
- One test that pauses and starts an additional swap before the transfer proof is sent (just after BTC locked). Results in the second swap redeeming and the first swap being refunded (because the transfer proof on Bob's side is lost). Once we store transfer proofs that we receive during executing a different swap into the database both swaps should redeem.

Note that the monero harness was adapted to allow creating wallets with multiple outputs, which is needed for Alice.
2021-04-13 18:16:19 +10:00

70 lines
2.2 KiB
Rust

use monero_harness::{Monero, MoneroWalletRpc};
use spectral::prelude::*;
use std::time::Duration;
use testcontainers::clients::Cli;
use tokio::time::sleep;
use tracing_subscriber::util::SubscriberInitExt;
#[tokio::test]
async fn fund_transfer_and_check_tx_key() {
let _guard = tracing_subscriber::fmt()
.with_env_filter("warn,test=debug,monero_harness=debug,monero_rpc=debug")
.set_default();
let fund_alice: u64 = 1_000_000_000_000;
let fund_bob = 0;
let send_to_bob = 5_000_000_000;
let tc = Cli::default();
let (monero, _containers) = Monero::new(&tc, vec!["alice".to_string(), "bob".to_string()])
.await
.unwrap();
let alice_wallet = monero.wallet("alice").unwrap();
let bob_wallet = monero.wallet("bob").unwrap();
monero.init_miner().await.unwrap();
monero.init_wallet("alice", vec![fund_alice]).await.unwrap();
monero.init_wallet("bob", vec![fund_bob]).await.unwrap();
monero.start_miner().await.unwrap();
// check alice balance
let got_alice_balance = alice_wallet.balance().await.unwrap();
assert_that(&got_alice_balance).is_equal_to(fund_alice);
// transfer from alice to bob
let bob_address = bob_wallet.address().await.unwrap().address;
let transfer = alice_wallet
.transfer(&bob_address, send_to_bob)
.await
.unwrap();
wait_for_wallet_to_catch_up(bob_wallet, send_to_bob).await;
let got_bob_balance = bob_wallet.balance().await.unwrap();
assert_that(&got_bob_balance).is_equal_to(send_to_bob);
// check if tx was actually seen
let tx_id = transfer.tx_hash;
let tx_key = transfer.tx_key;
let res = bob_wallet
.client()
.check_tx_key(&tx_id, &tx_key, &bob_address)
.await
.expect("failed to check tx by key");
assert_that!(res.received).is_equal_to(send_to_bob);
}
async fn wait_for_wallet_to_catch_up(wallet: &MoneroWalletRpc, expected_balance: u64) {
let max_retry = 15;
let mut retry = 0;
loop {
retry += 1;
let balance = wallet.balance().await.unwrap();
if balance == expected_balance || max_retry == retry {
break;
}
sleep(Duration::from_secs(1)).await;
}
}