Refactor Bob's side (happy path + alice restart)

Refactor Bob's test setup in the same way as Alice's.
Introduce BobHarness that allows creating and restarting as well as asserting redeemed for Bob.
pull/144/head
Daniel Karzel 4 years ago
parent 59f9a1c286
commit bede1c13dd

@ -1,5 +1,5 @@
use rand::rngs::OsRng;
use swap::protocol::{alice, bob, bob::BobState};
use swap::protocol::{alice, bob};
use tokio::join;
pub mod testutils;
@ -8,7 +8,7 @@ pub mod testutils;
#[tokio::test]
async fn happy_path() {
testutils::test(|alice_harness, bob, swap_amounts| async move {
testutils::test(|alice_harness, bob_harness| async move {
let alice = alice_harness.new_alice().await;
let alice_swap_fut = alice::swap(
alice.state,
@ -19,6 +19,8 @@ async fn happy_path() {
alice.swap_id,
alice.db,
);
let bob = bob_harness.new_bob().await;
let bob_swap_fut = bob::swap(
bob.state,
bob.event_loop_handle,
@ -31,15 +33,7 @@ async fn happy_path() {
let (alice_state, bob_state) = join!(alice_swap_fut, bob_swap_fut);
alice_harness.assert_redeemed(alice_state.unwrap()).await;
let btc_bob_final = bob.bitcoin_wallet.as_ref().balance().await.unwrap();
bob.monero_wallet.as_ref().inner.refresh().await.unwrap();
let xmr_bob_final = bob.monero_wallet.as_ref().get_balance().await.unwrap();
assert!(matches!(bob_state.unwrap(), BobState::XmrRedeemed));
assert!(btc_bob_final <= bob.btc_starting_balance - swap_amounts.btc);
assert_eq!(xmr_bob_final, bob.xmr_starting_balance + swap_amounts.xmr);
bob_harness.assert_redeemed(bob_state.unwrap()).await;
})
.await;
}

@ -1,12 +1,13 @@
use rand::rngs::OsRng;
use swap::protocol::{alice, alice::AliceState, bob, bob::BobState};
use swap::protocol::{alice, alice::AliceState, bob};
pub mod testutils;
#[tokio::test]
async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
testutils::test(|alice_harness, bob, swap_amounts| async move {
testutils::test(|alice_harness, bob_harness| async move {
let alice = alice_harness.new_alice().await;
let bob = bob_harness.new_bob().await;
let bob_swap_fut = bob::swap(
bob.state,
@ -51,12 +52,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
alice_harness.assert_redeemed(alice_state).await;
let bob_state = bob_swap_handle.await.unwrap();
let btc_bob_final = bob.bitcoin_wallet.as_ref().balance().await.unwrap();
bob.monero_wallet.as_ref().inner.refresh().await.unwrap();
let xmr_bob_final = bob.monero_wallet.as_ref().get_balance().await.unwrap();
assert!(matches!(bob_state.unwrap(), BobState::XmrRedeemed));
assert!(btc_bob_final <= bob.btc_starting_balance - swap_amounts.btc);
assert_eq!(xmr_bob_final, bob.xmr_starting_balance + swap_amounts.xmr);
bob_harness.assert_redeemed(bob_state.unwrap()).await
})
.await;
}

@ -38,17 +38,6 @@ pub struct Alice {
pub db: Database,
}
pub struct Bob {
pub state: BobState,
pub event_loop_handle: bob::EventLoopHandle,
pub db: Database,
pub bitcoin_wallet: Arc<bitcoin::Wallet>,
pub monero_wallet: Arc<monero::Wallet>,
pub swap_id: Uuid,
pub btc_starting_balance: bitcoin::Amount,
pub xmr_starting_balance: monero::Amount,
}
pub struct AliceHarness {
listen_address: Multiaddr,
peer_id: PeerId,
@ -57,7 +46,6 @@ pub struct AliceHarness {
db_path: PathBuf,
swap_id: Uuid,
// Stuff that should probably not be in here...
swap_amounts: SwapAmounts,
btc_wallet: Arc<bitcoin::Wallet>,
xmr_wallet: Arc<monero::Wallet>,
@ -189,9 +177,137 @@ impl AliceHarness {
}
}
pub struct Bob {
pub state: BobState,
pub event_loop_handle: bob::EventLoopHandle,
pub db: Database,
pub bitcoin_wallet: Arc<bitcoin::Wallet>,
pub monero_wallet: Arc<monero::Wallet>,
pub swap_id: Uuid,
}
pub struct BobHarness {
db_path: PathBuf,
swap_id: Uuid,
swap_amounts: SwapAmounts,
btc_wallet: Arc<bitcoin::Wallet>,
xmr_wallet: Arc<monero::Wallet>,
config: Config,
starting_balances: StartingBalances,
alice_connect_address: Multiaddr,
alice_connect_peer_id: PeerId,
}
impl BobHarness {
#[allow(clippy::too_many_arguments)]
pub async fn new(
config: Config,
swap_amounts: SwapAmounts,
swap_id: Uuid,
monero: &Monero,
bitcoind: &Bitcoind<'_>,
starting_balances: StartingBalances,
alice_connect_address: Multiaddr,
alice_connect_peer_id: PeerId,
) -> Self {
let db_path = tempdir().unwrap().path().to_path_buf();
let (btc_wallet, xmr_wallet) =
init_wallets("bob", bitcoind, monero, starting_balances.clone(), config).await;
Self {
db_path,
swap_id,
swap_amounts,
btc_wallet,
xmr_wallet,
config,
starting_balances,
alice_connect_address,
alice_connect_peer_id,
}
}
pub async fn new_bob(&self) -> Bob {
let initial_state = init_bob_state(
self.swap_amounts.btc,
self.swap_amounts.xmr,
self.btc_wallet.clone(),
self.config,
)
.await;
let (event_loop, event_loop_handle) = init_bob_event_loop(
self.alice_connect_peer_id.clone(),
self.alice_connect_address.clone(),
);
tokio::spawn(async move { event_loop.run().await });
let db = Database::open(self.db_path.as_path()).unwrap();
Bob {
state: initial_state,
event_loop_handle,
db,
bitcoin_wallet: self.btc_wallet.clone(),
monero_wallet: self.xmr_wallet.clone(),
swap_id: self.swap_id,
}
}
pub async fn recover_bob_from_db(&self) -> Bob {
// TODO: "simulated restart" issues:
// - create new wallets instead of reusing (hard because of container
// lifetimes)
// - consider aborting the old event loop (currently just keeps running)
// reopen the existing database
let db = Database::open(self.db_path.clone().as_path()).unwrap();
let resume_state =
if let swap::database::Swap::Bob(state) = db.get_state(self.swap_id).unwrap() {
state.into()
} else {
unreachable!()
};
let (event_loop, event_loop_handle) = init_bob_event_loop(
self.alice_connect_peer_id.clone(),
self.alice_connect_address.clone(),
);
tokio::spawn(async move { event_loop.run().await });
Bob {
state: resume_state,
event_loop_handle,
db,
bitcoin_wallet: self.btc_wallet.clone(),
monero_wallet: self.xmr_wallet.clone(),
swap_id: self.swap_id,
}
}
pub async fn assert_redeemed(&self, state: BobState) {
assert!(matches!(state, BobState::XmrRedeemed));
let btc_bob_final = self.btc_wallet.as_ref().balance().await.unwrap();
self.xmr_wallet.as_ref().inner.refresh().await.unwrap();
let xmr_bob_final = self.xmr_wallet.as_ref().get_balance().await.unwrap();
assert!(btc_bob_final <= self.starting_balances.btc - self.swap_amounts.btc);
assert_eq!(
xmr_bob_final,
self.starting_balances.xmr + self.swap_amounts.xmr
);
}
}
pub async fn test<T, F>(testfn: T)
where
T: Fn(AliceHarness, Bob, SwapAmounts) -> F,
T: Fn(AliceHarness, BobHarness) -> F,
F: Future<Output = ()>,
{
let cli = Cli::default();
@ -211,7 +327,7 @@ where
xmr: swap_amounts.xmr * 10,
btc: bitcoin::Amount::ZERO,
};
let alice_factory = AliceHarness::new(
let alice_harness = AliceHarness::new(
config,
swap_amounts,
Uuid::new_v4(),
@ -226,43 +342,19 @@ where
btc: swap_amounts.btc * 10,
};
let (bob_btc_wallet, bob_xmr_wallet) = init_wallets(
"bob",
&containers.bitcoind,
&monero,
bob_starting_balances.clone(),
config,
)
.await;
let bob_state = init_bob_state(
swap_amounts.btc,
swap_amounts.xmr,
bob_btc_wallet.clone(),
let bob_harness = BobHarness::new(
config,
swap_amounts,
Uuid::new_v4(),
&monero,
&containers.bitcoind,
bob_starting_balances,
alice_harness.listen_address(),
alice_harness.peer_id(),
)
.await;
let (bob_event_loop, bob_event_loop_handle) =
init_bob_event_loop(alice_factory.peer_id(), alice_factory.listen_address());
let bob_db_dir = tempdir().unwrap();
let bob_db = Database::open(bob_db_dir.path()).unwrap();
tokio::spawn(async move { bob_event_loop.run().await });
let bob = Bob {
state: bob_state,
event_loop_handle: bob_event_loop_handle,
db: bob_db,
bitcoin_wallet: bob_btc_wallet,
monero_wallet: bob_xmr_wallet,
swap_id: Uuid::new_v4(),
xmr_starting_balance: bob_starting_balances.xmr,
btc_starting_balance: bob_starting_balances.btc,
};
testfn(alice_factory, bob, swap_amounts).await
testfn(alice_harness, bob_harness).await
}
pub async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) {

Loading…
Cancel
Save