Allow Bob to exit execution at a specified state

This commit is contained in:
rishflab 2020-12-02 12:09:43 +11:00
parent 150e5f2aba
commit 584cc22024
2 changed files with 157 additions and 120 deletions

1
Cargo.lock generated
View File

@ -3369,6 +3369,7 @@ dependencies = [
"bitcoin", "bitcoin",
"bitcoin-harness", "bitcoin-harness",
"conquer-once", "conquer-once",
"conquer-once",
"derivative", "derivative",
"ecdsa_fun", "ecdsa_fun",
"futures", "futures",

View File

@ -33,10 +33,31 @@ pub enum BobState {
SafelyAborted, SafelyAborted,
} }
// State machine driver for swap execution
#[async_recursion]
pub async fn swap<R>( pub async fn swap<R>(
state: BobState, state: BobState,
swarm: Swarm,
db: Database,
bitcoin_wallet: Arc<crate::bitcoin::Wallet>,
monero_wallet: Arc<crate::monero::Wallet>,
rng: R,
swap_id: Uuid,
) -> Result<BobState>
where
R: RngCore + CryptoRng + Send,
{
run_until(state, is_complete, swarm, db, bitcoin_wallet, monero_wallet, rng, swap_id).await
}
// TODO: use macro or generics
pub fn is_complete(state: &BobState) -> bool {
matches!(state, BobState::BtcRefunded| BobState::XmrRedeemed | BobState::Punished | BobState::SafelyAborted)
}
// State machine driver for swap execution
#[async_recursion]
pub async fn run_until<R>(
state: BobState,
is_state: fn(&BobState) -> bool,
mut swarm: Swarm, mut swarm: Swarm,
db: Database, db: Database,
bitcoin_wallet: Arc<crate::bitcoin::Wallet>, bitcoin_wallet: Arc<crate::bitcoin::Wallet>,
@ -47,6 +68,9 @@ pub async fn swap<R>(
where where
R: RngCore + CryptoRng + Send, R: RngCore + CryptoRng + Send,
{ {
if is_state(&state) {
Ok(state)
} else {
match state { match state {
BobState::Started { BobState::Started {
state0, state0,
@ -63,8 +87,9 @@ where
bitcoin_wallet.clone(), bitcoin_wallet.clone(),
) )
.await?; .await?;
swap( run_until(
BobState::Negotiated(state2, peer_id), BobState::Negotiated(state2, peer_id),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -78,8 +103,9 @@ where
// Alice and Bob have exchanged info // Alice and Bob have exchanged info
let state3 = state2.lock_btc(bitcoin_wallet.as_ref()).await?; let state3 = state2.lock_btc(bitcoin_wallet.as_ref()).await?;
// db.insert_latest_state(state); // db.insert_latest_state(state);
swap( run_until(
BobState::BtcLocked(state3, alice_peer_id), BobState::BtcLocked(state3, alice_peer_id),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -101,8 +127,9 @@ where
} }
other => panic!("unexpected event: {:?}", other), other => panic!("unexpected event: {:?}", other),
}; };
swap( run_until(
BobState::XmrLocked(state4, alice_peer_id), BobState::XmrLocked(state4, alice_peer_id),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -133,8 +160,9 @@ where
other => panic!("unexpected event: {:?}", other), other => panic!("unexpected event: {:?}", other),
}; };
swap( run_until(
BobState::EncSigSent(state, alice_peer_id), BobState::EncSigSent(state, alice_peer_id),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -151,8 +179,9 @@ where
tokio::select! { tokio::select! {
val = redeem_watcher => { val = redeem_watcher => {
swap( run_until(
BobState::BtcRedeemed(val?), BobState::BtcRedeemed(val?),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -169,8 +198,9 @@ where
state.submit_tx_cancel(bitcoin_wallet.as_ref()).await?; state.submit_tx_cancel(bitcoin_wallet.as_ref()).await?;
} }
swap( run_until(
BobState::Cancelled(state), BobState::Cancelled(state),
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -186,8 +216,9 @@ where
BobState::BtcRedeemed(state) => { BobState::BtcRedeemed(state) => {
// Bob redeems XMR using revealed s_a // Bob redeems XMR using revealed s_a
state.claim_xmr(monero_wallet.as_ref()).await?; state.claim_xmr(monero_wallet.as_ref()).await?;
swap( run_until(
BobState::XmrRedeemed, BobState::XmrRedeemed,
is_state,
swarm, swarm,
db, db,
bitcoin_wallet, bitcoin_wallet,
@ -203,8 +234,13 @@ where
BobState::SafelyAborted => Ok(BobState::SafelyAborted), BobState::SafelyAborted => Ok(BobState::SafelyAborted),
BobState::XmrRedeemed => Ok(BobState::XmrRedeemed), BobState::XmrRedeemed => Ok(BobState::XmrRedeemed),
} }
}
} }
// // State machine driver for recovery execution // // State machine driver for recovery execution
// #[async_recursion] // #[async_recursion]
// pub async fn abort(state: BobState, io: Io) -> Result<BobState> { // pub async fn abort(state: BobState, io: Io) -> Result<BobState> {