From 69e1c2bb2711283dc1c5dd386c4dd036ebe3ea98 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 22 Dec 2020 16:28:14 +1100 Subject: [PATCH] Align Alice DB states with swap states --- Cargo.lock | 22 ++++++++++++++++++++++ swap/Cargo.toml | 1 + swap/src/alice/swap.rs | 38 +++++++++++++++++++++++--------------- swap/src/state.rs | 21 +++++++++++++++++---- swap/src/storage.rs | 8 ++++---- xmr-btc/src/alice.rs | 2 +- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9de62a8..620b74b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3289,6 +3289,27 @@ dependencies = [ "syn", ] +[[package]] +name = "strum" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "subtle" version = "1.0.0" @@ -3337,6 +3358,7 @@ dependencies = [ "sled", "spectral", "structopt", + "strum", "tempfile", "testcontainers", "time", diff --git a/swap/Cargo.toml b/swap/Cargo.toml index f30ae7e4..c4119c9d 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -34,6 +34,7 @@ serde_json = "1" sha2 = "0.9" sled = "0.34" structopt = "0.3" +strum = { version = "0.20", features = ["derive"] } tempfile = "3" time = "0.2" tokio = { version = "0.2", features = ["rt-threaded", "time", "macros", "sync"] } diff --git a/swap/src/alice/swap.rs b/swap/src/alice/swap.rs index 4c32b3c3..e20082f0 100644 --- a/swap/src/alice/swap.rs +++ b/swap/src/alice/swap.rs @@ -14,7 +14,7 @@ use crate::{ bitcoin::EncryptedSignature, network::request_response::AliceToBob, state, - state::{Alice, Swap}, + state::{Alice, EndState, Swap}, storage::Database, SwapAmounts, }; @@ -118,20 +118,23 @@ impl From<&AliceState> for state::Alice { state: state3.clone(), encrypted_signature: encrypted_signature.clone(), }, - AliceState::BtcRedeemed => Alice::SwapComplete, + AliceState::BtcRedeemed => Alice::Done(EndState::BtcRedeemed), AliceState::BtcCancelled { state3, .. } => Alice::BtcCancelled(state3.clone()), - AliceState::BtcRefunded { .. } => Alice::SwapComplete, + AliceState::BtcRefunded { spend_key, state3 } => Alice::BtcRefunded { + spend_key: *spend_key, + state3: state3.clone(), + }, AliceState::BtcPunishable { state3, .. } => Alice::BtcPunishable(state3.clone()), - AliceState::XmrRefunded => Alice::SwapComplete, + AliceState::XmrRefunded => Alice::Done(EndState::XmrRefunded), AliceState::CancelTimelockExpired { state3 } => { Alice::CancelTimelockExpired(state3.clone()) } - AliceState::BtcPunished => Alice::SwapComplete, - AliceState::SafelyAborted => Alice::SwapComplete, - // TODO: Potentially add support to resume swaps that are not Negotiated - AliceState::Started { .. } => { - panic!("Alice attempted to save swap before being negotiated") - } + AliceState::BtcPunished => Alice::Done(EndState::BtcPunished), + AliceState::SafelyAborted => Alice::Done(EndState::SafelyAborted), + AliceState::Started { amounts, state0 } => Alice::Started { + amounts: *amounts, + state0: state0.clone(), + }, } } } @@ -143,6 +146,7 @@ impl TryFrom for AliceState { 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 { @@ -198,15 +202,19 @@ impl TryFrom for AliceState { } } Alice::BtcRefunded { - state, spend_key, .. + state3: state, + spend_key, + .. } => BtcRefunded { spend_key, state3: state, }, - Alice::SwapComplete => { - // TODO(Franck): Better fine grain - AliceState::SafelyAborted - } + Alice::Done(end_state) => match end_state { + EndState::SafelyAborted => SafelyAborted, + EndState::BtcRedeemed => BtcRedeemed, + EndState::XmrRefunded => XmrRefunded, + EndState::BtcPunished => BtcPunished, + }, }; Ok(alice_state) } else { diff --git a/swap/src/state.rs b/swap/src/state.rs index 7d759321..0ddf2596 100644 --- a/swap/src/state.rs +++ b/swap/src/state.rs @@ -1,3 +1,4 @@ +use crate::SwapAmounts; use serde::{Deserialize, Serialize}; use std::fmt::Display; use xmr_btc::{alice, bitcoin::EncryptedSignature, bob, monero, serde::monero_private_key}; @@ -12,6 +13,10 @@ pub enum Swap { #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub enum Alice { + Started { + amounts: SwapAmounts, + state0: alice::State0, + }, Negotiated(alice::State3), BtcLocked(alice::State3), XmrLocked(alice::State3), @@ -28,12 +33,19 @@ pub enum Alice { BtcCancelled(alice::State3), BtcPunishable(alice::State3), BtcRefunded { - state: alice::State3, + state3: alice::State3, #[serde(with = "monero_private_key")] spend_key: monero::PrivateKey, - view_key: monero::PrivateViewKey, }, - SwapComplete, + Done(EndState), +} + +#[derive(Clone, strum::Display, Debug, Deserialize, Serialize, PartialEq)] +pub enum EndState { + SafelyAborted, + BtcRedeemed, + XmrRefunded, + BtcPunished, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -72,6 +84,7 @@ impl Display for Swap { impl Display for Alice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Alice::Started { .. } => write!(f, "Started"), Alice::Negotiated(_) => f.write_str("Handshake complete"), Alice::BtcLocked(_) => f.write_str("Bitcoin locked"), Alice::XmrLocked(_) => f.write_str("Monero locked"), @@ -80,7 +93,7 @@ impl Display for Alice { Alice::BtcCancelled(_) => f.write_str("Bitcoin cancel transaction published"), Alice::BtcPunishable(_) => f.write_str("Bitcoin punishable"), Alice::BtcRefunded { .. } => f.write_str("Monero refundable"), - Alice::SwapComplete => f.write_str("Swap complete"), + Alice::Done(end_state) => write!(f, "Done: {}", end_state), Alice::EncSigLearned { .. } => f.write_str("Encrypted signature learned"), } } diff --git a/swap/src/storage.rs b/swap/src/storage.rs index f26330fe..fd52c685 100644 --- a/swap/src/storage.rs +++ b/swap/src/storage.rs @@ -81,7 +81,7 @@ where #[cfg(test)] mod tests { - use crate::state::{Alice, Bob}; + use crate::state::{Alice, Bob, EndState}; use super::*; @@ -90,7 +90,7 @@ mod tests { let db_dir = tempfile::tempdir().unwrap(); let db = Database::open(db_dir.path()).unwrap(); - let state_1 = Swap::Alice(Alice::SwapComplete); + let state_1 = Swap::Alice(Alice::Done(EndState::BtcRedeemed)); let swap_id_1 = Uuid::new_v4(); db.insert_latest_state(swap_id_1, state_1.clone()) .await @@ -119,7 +119,7 @@ mod tests { let db_dir = tempfile::tempdir().unwrap(); let db = Database::open(db_dir.path()).unwrap(); - let state = Swap::Alice(Alice::SwapComplete); + let state = Swap::Alice(Alice::Done(EndState::SafelyAborted)); let swap_id = Uuid::new_v4(); db.insert_latest_state(swap_id, state.clone()) @@ -146,7 +146,7 @@ mod tests { let db_dir = tempfile::tempdir().unwrap(); let db = Database::open(db_dir.path()).unwrap(); - let state_1 = Swap::Alice(Alice::SwapComplete); + let state_1 = Swap::Alice(Alice::Done(EndState::BtcPunished)); let swap_id_1 = Uuid::new_v4(); db.insert_latest_state(swap_id_1, state_1.clone()) .await diff --git a/xmr-btc/src/alice.rs b/xmr-btc/src/alice.rs index 05e3798c..52418c51 100644 --- a/xmr-btc/src/alice.rs +++ b/xmr-btc/src/alice.rs @@ -435,7 +435,7 @@ impl State { } } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub struct State0 { pub a: bitcoin::SecretKey, pub s_a: cross_curve_dleq::Scalar,