Skip to content

Commit

Permalink
Finally: The actual test
Browse files Browse the repository at this point in the history
- Add a 3rd maker url in test_commons.
- the test file.
- Some doc loves to other tests.

So far implemented the "move on" phase after breakup .
A //TODO is include for "recovery after the breakup" situation.

Coming soon in next commit.
  • Loading branch information
rajarshimaitra committed Sep 5, 2023
1 parent 7a8db42 commit 4b1db48
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 10 deletions.
8 changes: 1 addition & 7 deletions src/test_commons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub static TEMP_FILES_DIR: &str = "tests/temp-files";
pub static TAKER: &str = "tests/temp-files/taker-wallet";
pub static MAKER1: &str = "tests/temp-files/maker-wallet-1";
pub static MAKER2: &str = "tests/temp-files/maker-wallet-2";
pub static MAKER3: &str = "tests/temp-files/maker-wallet-3";

// Helper function to create new wallet
pub fn create_wallet_and_import(filename: PathBuf, rpc_config: &RPCConfig) -> Wallet {
Expand Down Expand Up @@ -113,10 +114,3 @@ impl From<&TestFrameWork> for RPCConfig {
}
}
}

// impl Drop for TestFrameWork {
// fn drop(&mut self) {
// log::info!("Stopping bitcoind");
// let _ = self.bitcoind.client.stop().unwrap();
// }
// }
206 changes: 206 additions & 0 deletions tests/test_maker_stop_before_setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#![cfg(feature = "integration-test")]
use bitcoin::Amount;
use std::{
fs,
path::PathBuf,
str::FromStr,
sync::{Arc, RwLock},
thread,
time::Duration,
};
use teleport::{
maker::MakerBehavior,
taker::{SwapParams, Taker, TakerBehavior},
test_commons::*,
wallet::{RPCConfig, WalletMode},
};

/// This test demonstrates the situation where a Maker prematurely drops connections after doing
/// initial protocol handshake. This should not necessarily disrupt the round, the Taker will try to find
/// more makers in his address book and carry on as usual. The Taker will mark this Maker as "bad" and will
/// not swap this maker again.
#[tokio::test]
async fn test_abort_case_2_move_on_with_other_makers() {
teleport::scripts::setup_logger();

let test_framework = Arc::new(TestFrameWork::new(None));

let rpc_config = RPCConfig::from(test_framework.as_ref());

let mut taker_rpc_config = rpc_config.clone();
taker_rpc_config.wallet_name = "taker".to_string();

let mut maker1_rpc_config = rpc_config.clone();
maker1_rpc_config.wallet_name = "maker_1".to_string();

let mut maker2_rpc_config = rpc_config.clone();
maker2_rpc_config.wallet_name = "maker_2".to_string();

let mut maker3_rpc_config = rpc_config.clone();
maker3_rpc_config.wallet_name = "maker_3".to_string();

// create temp dir to hold wallet and .dat files if not exists
if !std::path::Path::new(TEMP_FILES_DIR).exists() {
fs::create_dir::<PathBuf>(TEMP_FILES_DIR.into()).unwrap();
}

let mut taker = Taker::init(
&PathBuf::from_str(TAKER).unwrap(),
Some(taker_rpc_config),
Some(WalletMode::Testing),
TakerBehavior::Normal,
)
.await
.unwrap();

// create maker1 wallet
let mut maker1_wallet = create_wallet_and_import(MAKER1.into(), &maker1_rpc_config);

// create maker2 wallet
let mut maker2_wallet = create_wallet_and_import(MAKER2.into(), &maker2_rpc_config);

// create maker3 wallet
let mut maker3_wallet = create_wallet_and_import(MAKER3.into(), &maker3_rpc_config);

// Check files are created
assert!(std::path::Path::new(TAKER).exists());
assert!(std::path::Path::new(MAKER1).exists());
assert!(std::path::Path::new(MAKER2).exists());
assert!(std::path::Path::new(MAKER3).exists());

// Create 3 taker and maker address and send 0.05 btc to each
for _ in 0..3 {
let taker_address = taker.get_wallet_mut().get_next_external_address().unwrap();
let maker1_address = maker1_wallet.get_next_external_address().unwrap();
let maker2_address = maker2_wallet.get_next_external_address().unwrap();
let maker3_address = maker3_wallet.get_next_external_address().unwrap();

test_framework.send_to_address(&taker_address, Amount::from_btc(0.05).unwrap());
test_framework.send_to_address(&maker1_address, Amount::from_btc(0.05).unwrap());
test_framework.send_to_address(&maker2_address, Amount::from_btc(0.05).unwrap());
test_framework.send_to_address(&maker3_address, Amount::from_btc(0.05).unwrap());
}

test_framework.generate_1_block();

// Check inital wallet assertions
assert_eq!(*taker.get_wallet().get_external_index(), 3);
assert_eq!(*maker1_wallet.get_external_index(), 3);
assert_eq!(*maker2_wallet.get_external_index(), 3);

assert_eq!(
taker
.get_wallet()
.list_unspent_from_wallet(false, true)
.unwrap()
.len(),
3
);
assert_eq!(
maker1_wallet
.list_unspent_from_wallet(false, true)
.unwrap()
.len(),
3
);
assert_eq!(
maker2_wallet
.list_unspent_from_wallet(false, true)
.unwrap()
.len(),
3
);

assert_eq!(
taker.get_wallet().lock_all_nonwallet_unspents().unwrap(),
()
);
assert_eq!(maker1_wallet.lock_all_nonwallet_unspents().unwrap(), ());
assert_eq!(maker2_wallet.lock_all_nonwallet_unspents().unwrap(), ());

let kill_flag = Arc::new(RwLock::new(false));

let maker1_config_clone = maker1_rpc_config.clone();
let kill_flag_maker_1 = kill_flag.clone();
let maker1_thread = thread::spawn(move || {
teleport::scripts::maker::run_maker(
&PathBuf::from_str(MAKER1).unwrap(),
&maker1_config_clone,
6102,
Some(WalletMode::Testing),
MakerBehavior::CloseOnSignSendersContractTx,
kill_flag_maker_1,
)
.unwrap();
});

let maker2_config_clone = maker2_rpc_config.clone();
let kill_flag_maker_2 = kill_flag.clone();
let maker3_thread = thread::spawn(move || {
teleport::scripts::maker::run_maker(
&PathBuf::from_str(MAKER2).unwrap(),
&maker2_config_clone,
16102,
Some(WalletMode::Testing),
MakerBehavior::Normal,
kill_flag_maker_2,
)
.unwrap();
});

let maker3_config_clone = maker3_rpc_config.clone();
let kill_flag_maker_3 = kill_flag.clone();
let maker2_thread = thread::spawn(move || {
teleport::scripts::maker::run_maker(
&PathBuf::from_str(MAKER3).unwrap(),
&maker3_config_clone,
26102,
Some(WalletMode::Testing),
MakerBehavior::Normal,
kill_flag_maker_3,
)
.unwrap();
});

let test_frameowrk_ptr = test_framework.clone();
let kill_block_creation_clone = kill_flag.clone();
let block_creation_thread = thread::spawn(move || {
while !*kill_block_creation_clone.read().unwrap() {
thread::sleep(Duration::from_secs(1));
test_frameowrk_ptr.generate_1_block();
log::info!("created block");
}
log::info!("ending block creation thread");
});

let swap_params = SwapParams {
send_amount: 500000,
maker_count: 2,
tx_count: 3,
required_confirms: 1,
fee_rate: 1000,
};

thread::sleep(Duration::from_secs(20));
taker.send_coinswap(swap_params).await.unwrap();
*kill_flag.write().unwrap() = true;
maker1_thread.join().unwrap();
maker2_thread.join().unwrap();
maker3_thread.join().unwrap();

block_creation_thread.join().unwrap();

// Maker gets banned for being naughty.
assert_eq!(
"localhost:6102",
taker.get_bad_makers()[0].address.to_string()
);

fs::remove_dir_all::<PathBuf>(TEMP_FILES_DIR.into()).unwrap();
test_framework.stop();
}

// TODO
// fn async fn test_abort_case_2_recover_if_no_mkars_found() {

// }
5 changes: 4 additions & 1 deletion tests/test_standard_coinswap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use bitcoin::Amount;
use teleport::{
maker::MakerBehavior,
taker::TakerBehavior,
test_commons::*,
wallet::{fidelity::YearAndMonth, RPCConfig, Wallet, WalletMode},
};
Expand All @@ -16,6 +17,8 @@ use std::{

use std::str::FromStr;

/// This test demonstrates a standard coinswap round between a Taker and 2 Makers. Nothing goes wrong
/// and the coinswap completes successfully.
#[tokio::test]
async fn test_standard_coinswap() {
teleport::scripts::setup_logger();
Expand Down Expand Up @@ -153,7 +156,7 @@ async fn test_standard_coinswap() {
500000,
2,
3,
None,
TakerBehavior::Normal,
);
});

Expand Down
11 changes: 9 additions & 2 deletions tests/test_taker_stop_after_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ use teleport::{
wallet::{RPCConfig, Wallet, WalletMode},
};

/// This test demonstrates the situation where the Taker drops connection after broadcasting all the
/// funding transactions. The Makers identifies this and waits for a timeout (5mins in prod, 30 secs in test)
/// for the Taker to come back. If the Taker doesn't come back within timeout, the Makers broadcasts the contract
/// transactions and reclaims their funds via timelock.
///
/// The Taker after coming live again will see unfinished coinswaps in his wallet. He can reclaim his funds via
/// broadcasting his contract transactions and claiming via timelock.
#[tokio::test]
async fn test_stop_taker_after_setup() {
teleport::scripts::setup_logger();
Expand Down Expand Up @@ -140,7 +147,7 @@ async fn test_stop_taker_after_setup() {
500000,
2,
3,
Some(TakerBehavior::DropConnectionAfterFullSetup),
TakerBehavior::DropConnectionAfterFullSetup,
);
});

Expand Down Expand Up @@ -169,7 +176,7 @@ async fn test_stop_taker_after_setup() {
&PathBuf::from_str(TAKER).unwrap(),
Some(taker_rpc_config),
Some(WalletMode::Testing),
TakerBehavior::None,
TakerBehavior::Normal,
)
.await
.unwrap();
Expand Down

0 comments on commit 4b1db48

Please sign in to comment.