Use from instead of try_from for Alice state conversion

This commit is contained in:
Franck Royer 2020-12-08 17:02:58 +11:00
parent caf903acda
commit c4cdd098fd
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
3 changed files with 79 additions and 54 deletions

View File

@ -26,11 +26,7 @@ use futures::{
}; };
use libp2p::request_response::ResponseChannel; use libp2p::request_response::ResponseChannel;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
use std::{ use std::{convert::TryFrom, fmt, sync::Arc};
convert::{TryFrom, TryInto},
fmt,
sync::Arc,
};
use tracing::info; use tracing::info;
use uuid::Uuid; use uuid::Uuid;
use xmr_btc::{ use xmr_btc::{
@ -111,37 +107,41 @@ impl fmt::Display for AliceState {
} }
} }
impl TryFrom<&AliceState> for state::Swap { impl From<&AliceState> for state::Alice {
type Error = anyhow::Error; fn from(alice_state: &AliceState) -> Self {
match alice_state {
fn try_from(alice_state: &AliceState) -> Result<Self> { AliceState::Started {
use state::{Alice::*, Swap::Alice}; amounts,
a,
let state = match alice_state { s_a,
AliceState::Started { .. } => bail!("Does not support storing `Started state."), v_a,
AliceState::Negotiated { state3, .. } => Negotiated(state3.clone()), } => Alice::Started {
AliceState::BtcLocked { state3, .. } => BtcLocked(state3.clone()), amounts: *amounts,
AliceState::XmrLocked { state3 } => XmrLocked(state3.clone()), 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 { AliceState::EncSignLearned {
state3, state3,
encrypted_signature, encrypted_signature,
} => EncSignLearned { } => Alice::EncSignLearned {
state: state3.clone(), state: state3.clone(),
encrypted_signature: encrypted_signature.clone(), encrypted_signature: encrypted_signature.clone(),
}, },
AliceState::BtcRedeemed => SwapComplete, AliceState::BtcRedeemed => Alice::SwapComplete,
AliceState::BtcCancelled { state3, .. } => BtcCancelled(state3.clone()), AliceState::BtcCancelled { state3, .. } => Alice::BtcCancelled(state3.clone()),
AliceState::BtcRefunded { .. } => SwapComplete, AliceState::BtcRefunded { .. } => Alice::SwapComplete,
AliceState::BtcPunishable { state3, .. } => BtcPunishable(state3.clone()), AliceState::BtcPunishable { state3, .. } => Alice::BtcPunishable(state3.clone()),
AliceState::XmrRefunded => SwapComplete, AliceState::XmrRefunded => Alice::SwapComplete,
// TODO(Franck): it may be more efficient to store the fact that we already want to // TODO(Franck): it may be more efficient to store the fact that we already want to
// abort // abort
AliceState::Cancelling { state3 } => XmrLocked(state3.clone()), AliceState::Cancelling { state3 } => Alice::XmrLocked(state3.clone()),
AliceState::Punished => SwapComplete, AliceState::Punished => Alice::SwapComplete,
AliceState::SafelyAborted => SwapComplete, AliceState::SafelyAborted => Alice::SwapComplete,
}; }
Ok(Alice(state))
} }
} }
@ -152,6 +152,7 @@ impl TryFrom<state::Swap> for AliceState {
use AliceState::*; use AliceState::*;
if let Swap::Alice(state) = db_state { if let Swap::Alice(state) = db_state {
let alice_state = match state { let alice_state = match state {
Alice::Started { .. } => todo!(),
Alice::Negotiated(state3) => Negotiated { Alice::Negotiated(state3) => Negotiated {
channel: None, channel: None,
amounts: SwapAmounts { amounts: SwapAmounts {
@ -288,8 +289,9 @@ pub async fn run_until(
state3, state3,
}; };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -330,8 +332,9 @@ pub async fn run_until(
} }
}; };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -370,8 +373,9 @@ pub async fn run_until(
} }
}; };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -409,8 +413,9 @@ pub async fn run_until(
_ => AliceState::Cancelling { state3 }, _ => AliceState::Cancelling { state3 },
}; };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -438,8 +443,9 @@ pub async fn run_until(
Ok(tx) => tx, Ok(tx) => tx,
Err(_) => { Err(_) => {
let state = AliceState::Cancelling { state3 }; let state = AliceState::Cancelling { state3 };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
return run_until( return run_until(
state, state,
is_target_state, is_target_state,
@ -465,8 +471,9 @@ pub async fn run_until(
.await?; .await?;
let state = AliceState::BtcRedeemed; let state = AliceState::BtcRedeemed;
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -491,8 +498,9 @@ pub async fn run_until(
.await?; .await?;
let state = AliceState::BtcCancelled { state3, tx_cancel }; let state = AliceState::BtcCancelled { state3, tx_cancel };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -523,8 +531,9 @@ pub async fn run_until(
match published_refund_tx { match published_refund_tx {
None => { None => {
let state = AliceState::BtcPunishable { tx_refund, state3 }; let state = AliceState::BtcPunishable { tx_refund, state3 };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
swap( swap(
state, state,
event_loop_handle, event_loop_handle,
@ -546,8 +555,9 @@ pub async fn run_until(
)?; )?;
let state = AliceState::BtcRefunded { spend_key, state3 }; let state = AliceState::BtcRefunded { spend_key, state3 };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -570,8 +580,9 @@ pub async fn run_until(
.await?; .await?;
let state = AliceState::XmrRefunded; let state = AliceState::XmrRefunded;
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
Ok((state, event_loop_handle)) Ok((state, event_loop_handle))
} }
AliceState::BtcPunishable { tx_refund, state3 } => { AliceState::BtcPunishable { tx_refund, state3 } => {
@ -599,8 +610,9 @@ pub async fn run_until(
match select(punish_tx_finalised, refund_tx_seen).await { match select(punish_tx_finalised, refund_tx_seen).await {
Either::Left(_) => { Either::Left(_) => {
let state = AliceState::Punished; let state = AliceState::Punished;
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,
@ -622,8 +634,9 @@ pub async fn run_until(
state3.S_b_bitcoin, state3.S_b_bitcoin,
)?; )?;
let state = AliceState::BtcRefunded { spend_key, state3 }; let state = AliceState::BtcRefunded { spend_key, state3 };
let db_state = (&state).try_into()?; let db_state = (&state).into();
db.insert_latest_state(swap_id, db_state).await?; db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?;
run_until( run_until(
state, state,
is_target_state, is_target_state,

View File

@ -49,7 +49,10 @@ pub async fn alice_recover(
state: Alice, state: Alice,
) -> Result<()> { ) -> Result<()> {
match state { match state {
Alice::Negotiated(_) | Alice::BtcLocked(_) | Alice::SwapComplete => { Alice::Started { .. }
| Alice::Negotiated(_)
| Alice::BtcLocked(_)
| Alice::SwapComplete => {
info!("Nothing to do"); info!("Nothing to do");
} }
Alice::XmrLocked(state) => { Alice::XmrLocked(state) => {

View File

@ -2,7 +2,9 @@ use crate::SwapAmounts;
use libp2p::{core::Multiaddr, PeerId}; use libp2p::{core::Multiaddr, PeerId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::Display; 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)] #[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
@ -14,6 +16,12 @@ pub enum Swap {
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub enum Alice { pub enum Alice {
Started {
amounts: SwapAmounts,
a: crate::bitcoin::SecretKey,
s_a: cross_curve_dleq::Scalar,
v_a: monero::PrivateViewKey,
},
Negotiated(alice::State3), Negotiated(alice::State3),
BtcLocked(alice::State3), BtcLocked(alice::State3),
XmrLocked(alice::State3), XmrLocked(alice::State3),
@ -93,6 +101,7 @@ impl Display for Swap {
impl Display for Alice { impl Display for Alice {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Alice::Started { .. } => f.write_str("Swap started"),
Alice::Negotiated(_) => f.write_str("Handshake complete"), Alice::Negotiated(_) => f.write_str("Handshake complete"),
Alice::BtcLocked(_) => f.write_str("Bitcoin locked"), Alice::BtcLocked(_) => f.write_str("Bitcoin locked"),
Alice::XmrLocked(_) => f.write_str("Monero locked"), Alice::XmrLocked(_) => f.write_str("Monero locked"),