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-harness",
"conquer-once",
"conquer-once",
"derivative",
"ecdsa_fun",
"futures",

View File

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