From e541f7b83d8c4d154fdea716f65c9470726c2e89 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 22 Dec 2020 16:36:27 +1100 Subject: [PATCH] Replace `TryFrom` with `From` for Alice states --- swap/src/alice/swap.rs | 142 ++++++++++++------------- swap/src/bin/swap.rs | 12 ++- swap/src/state.rs | 6 -- swap/tests/happy_path_restart_alice.rs | 15 ++- 4 files changed, 81 insertions(+), 94 deletions(-) diff --git a/swap/src/alice/swap.rs b/swap/src/alice/swap.rs index e20082f0..dff383d0 100644 --- a/swap/src/alice/swap.rs +++ b/swap/src/alice/swap.rs @@ -18,7 +18,7 @@ use crate::{ storage::Database, SwapAmounts, }; -use anyhow::{bail, Result}; +use anyhow::Result; use async_recursion::async_recursion; use futures::{ future::{select, Either}, @@ -26,7 +26,7 @@ use futures::{ }; use libp2p::request_response::ResponseChannel; use rand::{CryptoRng, RngCore}; -use std::{convert::TryFrom, fmt, sync::Arc}; +use std::{fmt, sync::Arc}; use tracing::info; use uuid::Uuid; use xmr_btc::{ @@ -139,86 +139,76 @@ impl From<&AliceState> for state::Alice { } } -impl TryFrom for AliceState { - type Error = anyhow::Error; - - fn try_from(db_state: Swap) -> Result { +impl From for AliceState { + fn from(db_state: state::Alice) -> Self { use AliceState::*; - if let Swap::Alice(state) = db_state { - let alice_state = match state { - Alice::Started { amounts, state0 } => Started { amounts, state0 }, - Alice::Negotiated(state3) => Negotiated { - channel: None, - amounts: SwapAmounts { - btc: state3.btc, - xmr: state3.xmr, - }, - state3, + match db_state { + Alice::Started { amounts, state0 } => Started { amounts, state0 }, + Alice::Negotiated(state3) => Negotiated { + channel: None, + amounts: SwapAmounts { + btc: state3.btc, + xmr: state3.xmr, }, - Alice::BtcLocked(state3) => BtcLocked { - channel: None, - amounts: SwapAmounts { - btc: state3.btc, - xmr: state3.xmr, - }, - state3, + state3, + }, + Alice::BtcLocked(state3) => BtcLocked { + channel: None, + amounts: SwapAmounts { + btc: state3.btc, + xmr: state3.xmr, }, - Alice::XmrLocked(state3) => XmrLocked { state3 }, - Alice::BtcRedeemable { .. } => bail!("BtcRedeemable state is unexpected"), - Alice::EncSigLearned { - state, - encrypted_signature, - } => EncSigLearned { - state3: state, - encrypted_signature, - }, - Alice::CancelTimelockExpired(state3) => { - AliceState::CancelTimelockExpired { state3 } - } - Alice::BtcCancelled(state) => { - let tx_cancel = bitcoin::TxCancel::new( - &state.tx_lock, - state.cancel_timelock, - state.a.public(), - state.B, - ); + state3, + }, + Alice::XmrLocked(state3) => XmrLocked { state3 }, + Alice::EncSigLearned { + state, + encrypted_signature, + } => EncSigLearned { + state3: state, + encrypted_signature, + }, + Alice::CancelTimelockExpired(state3) => AliceState::CancelTimelockExpired { state3 }, + Alice::BtcCancelled(state) => { + let tx_cancel = bitcoin::TxCancel::new( + &state.tx_lock, + state.cancel_timelock, + state.a.public(), + state.B, + ); - BtcCancelled { - state3: state, - tx_cancel, - } - } - Alice::BtcPunishable(state) => { - let tx_cancel = bitcoin::TxCancel::new( - &state.tx_lock, - state.cancel_timelock, - state.a.public(), - state.B, - ); - let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &state.refund_address); - BtcPunishable { - tx_refund, - state3: state, - } - } - Alice::BtcRefunded { + BtcCancelled { state3: state, - spend_key, - .. - } => BtcRefunded { - spend_key, + tx_cancel, + } + } + Alice::BtcPunishable(state) => { + let tx_cancel = bitcoin::TxCancel::new( + &state.tx_lock, + state.cancel_timelock, + state.a.public(), + state.B, + ); + let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &state.refund_address); + BtcPunishable { + tx_refund, state3: state, - }, - Alice::Done(end_state) => match end_state { - EndState::SafelyAborted => SafelyAborted, - EndState::BtcRedeemed => BtcRedeemed, - EndState::XmrRefunded => XmrRefunded, - EndState::BtcPunished => BtcPunished, - }, - }; - Ok(alice_state) - } else { - bail!("Alice swap state expected.") + } + } + Alice::BtcRefunded { + state3: state, + spend_key, + .. + } => BtcRefunded { + spend_key, + state3: state, + }, + Alice::Done(end_state) => match end_state { + EndState::SafelyAborted => SafelyAborted, + EndState::BtcRedeemed => BtcRedeemed, + EndState::XmrRefunded => XmrRefunded, + EndState::BtcPunished => BtcPunished, + }, } } } diff --git a/swap/src/bin/swap.rs b/swap/src/bin/swap.rs index 0a25ebe3..8ec72734 100644 --- a/swap/src/bin/swap.rs +++ b/swap/src/bin/swap.rs @@ -12,7 +12,7 @@ )] #![forbid(unsafe_code)] -use anyhow::{Context, Result}; +use anyhow::{bail, Context, Result}; use libp2p::{core::Multiaddr, PeerId}; use prettytable::{row, Table}; use rand::rngs::OsRng; @@ -26,6 +26,7 @@ use swap::{ cli::{Command, Options, Resume}, monero, network::transport::build, + state::Swap, storage::Database, trace::init_tracing, SwapAmounts, @@ -180,9 +181,12 @@ async fn main() -> Result<()> { monero_wallet_rpc_url, listen_addr, }) => { - let db_swap = db.get_state(swap_id)?; + let db_state = if let Swap::Alice(db_state) = db.get_state(swap_id)? { + db_state + } else { + bail!("Swap {} is not sell xmr.", swap_id) + }; - let alice_state = AliceState::try_from(db_swap.clone())?; let (bitcoin_wallet, monero_wallet) = setup_wallets( bitcoind_url, bitcoin_wallet_name.as_str(), @@ -192,7 +196,7 @@ async fn main() -> Result<()> { .await?; alice_swap( swap_id, - alice_state, + db_state.into(), listen_addr, bitcoin_wallet, monero_wallet, diff --git a/swap/src/state.rs b/swap/src/state.rs index 0ddf2596..ad2996ac 100644 --- a/swap/src/state.rs +++ b/swap/src/state.rs @@ -20,11 +20,6 @@ pub enum Alice { Negotiated(alice::State3), BtcLocked(alice::State3), XmrLocked(alice::State3), - // TODO(Franck): Delete this state as it is not used in alice::swap - BtcRedeemable { - state: alice::State3, - redeem_tx: bitcoin::Transaction, - }, EncSigLearned { state: alice::State3, encrypted_signature: EncryptedSignature, @@ -88,7 +83,6 @@ impl Display for Alice { Alice::Negotiated(_) => f.write_str("Handshake complete"), Alice::BtcLocked(_) => f.write_str("Bitcoin locked"), Alice::XmrLocked(_) => f.write_str("Monero locked"), - Alice::BtcRedeemable { .. } => f.write_str("Bitcoin redeemable"), Alice::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"), Alice::BtcCancelled(_) => f.write_str("Bitcoin cancel transaction published"), Alice::BtcPunishable(_) => f.write_str("Bitcoin punishable"), diff --git a/swap/tests/happy_path_restart_alice.rs b/swap/tests/happy_path_restart_alice.rs index 6b1ad0cd..d2dfd9d8 100644 --- a/swap/tests/happy_path_restart_alice.rs +++ b/swap/tests/happy_path_restart_alice.rs @@ -2,7 +2,6 @@ use crate::testutils::{init_alice, init_bob}; use get_port::get_port; use libp2p::Multiaddr; use rand::rngs::OsRng; -use std::convert::TryFrom; use swap::{alice, alice::swap::AliceState, bitcoin, bob, storage::Database}; use tempfile::tempdir; use testcontainers::clients::Cli; @@ -111,19 +110,19 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() { assert!(matches!(alice_state, AliceState::EncSigLearned {..})); let alice_db = Database::open(alice_db_datadir.path()).unwrap(); - let state_before_restart = alice_db.get_state(alice_swap_id).unwrap(); - if let swap::state::Swap::Alice(state) = state_before_restart.clone() { - assert!(matches!(state, swap::state::Alice::EncSigLearned {..})); - } + let resume_state = + if let swap::state::Swap::Alice(state) = alice_db.get_state(alice_swap_id).unwrap() { + assert!(matches!(state, swap::state::Alice::EncSigLearned {..})); + state.into() + } else { + unreachable!() + }; let (mut event_loop_after_restart, event_loop_handle_after_restart) = testutils::init_alice_event_loop(alice_multiaddr); tokio::spawn(async move { event_loop_after_restart.run().await }); - let db_swap = alice_db.get_state(alice_swap_id).unwrap(); - let resume_state = AliceState::try_from(db_swap).unwrap(); - let alice_state = alice::swap::swap( resume_state, event_loop_handle_after_restart,