From c4cdd098fd6acda2bd729d96c491e20911210d40 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 8 Dec 2020 17:02:58 +1100 Subject: [PATCH] Use from instead of try_from for Alice state conversion --- swap/src/alice/swap.rs | 117 +++++++++++++++++++++++------------------ swap/src/recover.rs | 5 +- swap/src/state.rs | 11 +++- 3 files changed, 79 insertions(+), 54 deletions(-) diff --git a/swap/src/alice/swap.rs b/swap/src/alice/swap.rs index 6354f6cc..0a6c54d4 100644 --- a/swap/src/alice/swap.rs +++ b/swap/src/alice/swap.rs @@ -26,11 +26,7 @@ use futures::{ }; use libp2p::request_response::ResponseChannel; use rand::{CryptoRng, RngCore}; -use std::{ - convert::{TryFrom, TryInto}, - fmt, - sync::Arc, -}; +use std::{convert::TryFrom, fmt, sync::Arc}; use tracing::info; use uuid::Uuid; use xmr_btc::{ @@ -111,37 +107,41 @@ impl fmt::Display for AliceState { } } -impl TryFrom<&AliceState> for state::Swap { - type Error = anyhow::Error; - - fn try_from(alice_state: &AliceState) -> Result { - use state::{Alice::*, Swap::Alice}; - - let state = match alice_state { - AliceState::Started { .. } => bail!("Does not support storing `Started state."), - AliceState::Negotiated { state3, .. } => Negotiated(state3.clone()), - AliceState::BtcLocked { state3, .. } => BtcLocked(state3.clone()), - AliceState::XmrLocked { state3 } => XmrLocked(state3.clone()), +impl From<&AliceState> for state::Alice { + fn from(alice_state: &AliceState) -> Self { + match alice_state { + AliceState::Started { + amounts, + a, + s_a, + v_a, + } => Alice::Started { + amounts: *amounts, + a: a.clone(), + s_a: *s_a, + v_a: *v_a, + }, + AliceState::Negotiated { state3, .. } => Alice::Negotiated(state3.clone()), + AliceState::BtcLocked { state3, .. } => Alice::BtcLocked(state3.clone()), + AliceState::XmrLocked { state3 } => Alice::XmrLocked(state3.clone()), AliceState::EncSignLearned { state3, encrypted_signature, - } => EncSignLearned { + } => Alice::EncSignLearned { state: state3.clone(), encrypted_signature: encrypted_signature.clone(), }, - AliceState::BtcRedeemed => SwapComplete, - AliceState::BtcCancelled { state3, .. } => BtcCancelled(state3.clone()), - AliceState::BtcRefunded { .. } => SwapComplete, - AliceState::BtcPunishable { state3, .. } => BtcPunishable(state3.clone()), - AliceState::XmrRefunded => SwapComplete, + AliceState::BtcRedeemed => Alice::SwapComplete, + AliceState::BtcCancelled { state3, .. } => Alice::BtcCancelled(state3.clone()), + AliceState::BtcRefunded { .. } => Alice::SwapComplete, + AliceState::BtcPunishable { state3, .. } => Alice::BtcPunishable(state3.clone()), + AliceState::XmrRefunded => Alice::SwapComplete, // TODO(Franck): it may be more efficient to store the fact that we already want to // abort - AliceState::Cancelling { state3 } => XmrLocked(state3.clone()), - AliceState::Punished => SwapComplete, - AliceState::SafelyAborted => SwapComplete, - }; - - Ok(Alice(state)) + AliceState::Cancelling { state3 } => Alice::XmrLocked(state3.clone()), + AliceState::Punished => Alice::SwapComplete, + AliceState::SafelyAborted => Alice::SwapComplete, + } } } @@ -152,6 +152,7 @@ impl TryFrom for AliceState { use AliceState::*; if let Swap::Alice(state) = db_state { let alice_state = match state { + Alice::Started { .. } => todo!(), Alice::Negotiated(state3) => Negotiated { channel: None, amounts: SwapAmounts { @@ -288,8 +289,9 @@ pub async fn run_until( state3, }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -330,8 +332,9 @@ pub async fn run_until( } }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -370,8 +373,9 @@ pub async fn run_until( } }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -409,8 +413,9 @@ pub async fn run_until( _ => AliceState::Cancelling { state3 }, }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -438,8 +443,9 @@ pub async fn run_until( Ok(tx) => tx, Err(_) => { let state = AliceState::Cancelling { state3 }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; return run_until( state, is_target_state, @@ -465,8 +471,9 @@ pub async fn run_until( .await?; let state = AliceState::BtcRedeemed; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -491,8 +498,9 @@ pub async fn run_until( .await?; let state = AliceState::BtcCancelled { state3, tx_cancel }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -523,8 +531,9 @@ pub async fn run_until( match published_refund_tx { None => { let state = AliceState::BtcPunishable { tx_refund, state3 }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; swap( state, event_loop_handle, @@ -546,8 +555,9 @@ pub async fn run_until( )?; let state = AliceState::BtcRefunded { spend_key, state3 }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -570,8 +580,9 @@ pub async fn run_until( .await?; let state = AliceState::XmrRefunded; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; Ok((state, event_loop_handle)) } AliceState::BtcPunishable { tx_refund, state3 } => { @@ -599,8 +610,9 @@ pub async fn run_until( match select(punish_tx_finalised, refund_tx_seen).await { Either::Left(_) => { let state = AliceState::Punished; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, @@ -622,8 +634,9 @@ pub async fn run_until( state3.S_b_bitcoin, )?; let state = AliceState::BtcRefunded { spend_key, state3 }; - let db_state = (&state).try_into()?; - db.insert_latest_state(swap_id, db_state).await?; + let db_state = (&state).into(); + db.insert_latest_state(swap_id, Swap::Alice(db_state)) + .await?; run_until( state, is_target_state, diff --git a/swap/src/recover.rs b/swap/src/recover.rs index 47c04362..1beae16f 100644 --- a/swap/src/recover.rs +++ b/swap/src/recover.rs @@ -49,7 +49,10 @@ pub async fn alice_recover( state: Alice, ) -> Result<()> { match state { - Alice::Negotiated(_) | Alice::BtcLocked(_) | Alice::SwapComplete => { + Alice::Started { .. } + | Alice::Negotiated(_) + | Alice::BtcLocked(_) + | Alice::SwapComplete => { info!("Nothing to do"); } Alice::XmrLocked(state) => { diff --git a/swap/src/state.rs b/swap/src/state.rs index 59c64ec8..13600d18 100644 --- a/swap/src/state.rs +++ b/swap/src/state.rs @@ -2,7 +2,9 @@ use crate::SwapAmounts; use libp2p::{core::Multiaddr, PeerId}; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use xmr_btc::{alice, bitcoin::EncryptedSignature, bob, monero, serde::monero_private_key}; +use xmr_btc::{ + alice, bitcoin::EncryptedSignature, bob, cross_curve_dleq, monero, serde::monero_private_key, +}; #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -14,6 +16,12 @@ pub enum Swap { #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub enum Alice { + Started { + amounts: SwapAmounts, + a: crate::bitcoin::SecretKey, + s_a: cross_curve_dleq::Scalar, + v_a: monero::PrivateViewKey, + }, Negotiated(alice::State3), BtcLocked(alice::State3), XmrLocked(alice::State3), @@ -93,6 +101,7 @@ impl Display for Swap { impl Display for Alice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Alice::Started { .. } => f.write_str("Swap started"), Alice::Negotiated(_) => f.write_str("Handshake complete"), Alice::BtcLocked(_) => f.write_str("Bitcoin locked"), Alice::XmrLocked(_) => f.write_str("Monero locked"),