Replace TryFrom with From for Alice states

This commit is contained in:
Franck Royer 2020-12-22 16:36:27 +11:00
parent 69e1c2bb27
commit e541f7b83d
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
4 changed files with 81 additions and 94 deletions

View File

@ -18,7 +18,7 @@ use crate::{
storage::Database, storage::Database,
SwapAmounts, SwapAmounts,
}; };
use anyhow::{bail, Result}; use anyhow::Result;
use async_recursion::async_recursion; use async_recursion::async_recursion;
use futures::{ use futures::{
future::{select, Either}, future::{select, Either},
@ -26,7 +26,7 @@ use futures::{
}; };
use libp2p::request_response::ResponseChannel; use libp2p::request_response::ResponseChannel;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
use std::{convert::TryFrom, fmt, sync::Arc}; use std::{fmt, sync::Arc};
use tracing::info; use tracing::info;
use uuid::Uuid; use uuid::Uuid;
use xmr_btc::{ use xmr_btc::{
@ -139,86 +139,76 @@ impl From<&AliceState> for state::Alice {
} }
} }
impl TryFrom<state::Swap> for AliceState { impl From<state::Alice> for AliceState {
type Error = anyhow::Error; fn from(db_state: state::Alice) -> Self {
fn try_from(db_state: Swap) -> Result<Self, Self::Error> {
use AliceState::*; use AliceState::*;
if let Swap::Alice(state) = db_state { match db_state {
let alice_state = match state { Alice::Started { amounts, state0 } => Started { amounts, state0 },
Alice::Started { amounts, state0 } => Started { amounts, state0 }, Alice::Negotiated(state3) => Negotiated {
Alice::Negotiated(state3) => Negotiated { channel: None,
channel: None, amounts: SwapAmounts {
amounts: SwapAmounts { btc: state3.btc,
btc: state3.btc, xmr: state3.xmr,
xmr: state3.xmr,
},
state3,
}, },
Alice::BtcLocked(state3) => BtcLocked { state3,
channel: None, },
amounts: SwapAmounts { Alice::BtcLocked(state3) => BtcLocked {
btc: state3.btc, channel: None,
xmr: state3.xmr, amounts: SwapAmounts {
}, btc: state3.btc,
state3, xmr: state3.xmr,
}, },
Alice::XmrLocked(state3) => XmrLocked { state3 }, state3,
Alice::BtcRedeemable { .. } => bail!("BtcRedeemable state is unexpected"), },
Alice::EncSigLearned { Alice::XmrLocked(state3) => XmrLocked { state3 },
state, Alice::EncSigLearned {
encrypted_signature, state,
} => EncSigLearned { encrypted_signature,
state3: state, } => EncSigLearned {
encrypted_signature, state3: state,
}, encrypted_signature,
Alice::CancelTimelockExpired(state3) => { },
AliceState::CancelTimelockExpired { state3 } Alice::CancelTimelockExpired(state3) => AliceState::CancelTimelockExpired { state3 },
} Alice::BtcCancelled(state) => {
Alice::BtcCancelled(state) => { let tx_cancel = bitcoin::TxCancel::new(
let tx_cancel = bitcoin::TxCancel::new( &state.tx_lock,
&state.tx_lock, state.cancel_timelock,
state.cancel_timelock, state.a.public(),
state.a.public(), state.B,
state.B, );
);
BtcCancelled { 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 {
state3: state, state3: state,
spend_key, tx_cancel,
.. }
} => BtcRefunded { }
spend_key, 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, state3: state,
}, }
Alice::Done(end_state) => match end_state { }
EndState::SafelyAborted => SafelyAborted, Alice::BtcRefunded {
EndState::BtcRedeemed => BtcRedeemed, state3: state,
EndState::XmrRefunded => XmrRefunded, spend_key,
EndState::BtcPunished => BtcPunished, ..
}, } => BtcRefunded {
}; spend_key,
Ok(alice_state) state3: state,
} else { },
bail!("Alice swap state expected.") Alice::Done(end_state) => match end_state {
EndState::SafelyAborted => SafelyAborted,
EndState::BtcRedeemed => BtcRedeemed,
EndState::XmrRefunded => XmrRefunded,
EndState::BtcPunished => BtcPunished,
},
} }
} }
} }

View File

@ -12,7 +12,7 @@
)] )]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
use anyhow::{Context, Result}; use anyhow::{bail, Context, Result};
use libp2p::{core::Multiaddr, PeerId}; use libp2p::{core::Multiaddr, PeerId};
use prettytable::{row, Table}; use prettytable::{row, Table};
use rand::rngs::OsRng; use rand::rngs::OsRng;
@ -26,6 +26,7 @@ use swap::{
cli::{Command, Options, Resume}, cli::{Command, Options, Resume},
monero, monero,
network::transport::build, network::transport::build,
state::Swap,
storage::Database, storage::Database,
trace::init_tracing, trace::init_tracing,
SwapAmounts, SwapAmounts,
@ -180,9 +181,12 @@ async fn main() -> Result<()> {
monero_wallet_rpc_url, monero_wallet_rpc_url,
listen_addr, 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( let (bitcoin_wallet, monero_wallet) = setup_wallets(
bitcoind_url, bitcoind_url,
bitcoin_wallet_name.as_str(), bitcoin_wallet_name.as_str(),
@ -192,7 +196,7 @@ async fn main() -> Result<()> {
.await?; .await?;
alice_swap( alice_swap(
swap_id, swap_id,
alice_state, db_state.into(),
listen_addr, listen_addr,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, monero_wallet,

View File

@ -20,11 +20,6 @@ pub enum Alice {
Negotiated(alice::State3), Negotiated(alice::State3),
BtcLocked(alice::State3), BtcLocked(alice::State3),
XmrLocked(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 { EncSigLearned {
state: alice::State3, state: alice::State3,
encrypted_signature: EncryptedSignature, encrypted_signature: EncryptedSignature,
@ -88,7 +83,6 @@ impl Display for Alice {
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"),
Alice::BtcRedeemable { .. } => f.write_str("Bitcoin redeemable"),
Alice::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"), Alice::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"),
Alice::BtcCancelled(_) => f.write_str("Bitcoin cancel transaction published"), Alice::BtcCancelled(_) => f.write_str("Bitcoin cancel transaction published"),
Alice::BtcPunishable(_) => f.write_str("Bitcoin punishable"), Alice::BtcPunishable(_) => f.write_str("Bitcoin punishable"),

View File

@ -2,7 +2,6 @@ use crate::testutils::{init_alice, init_bob};
use get_port::get_port; use get_port::get_port;
use libp2p::Multiaddr; use libp2p::Multiaddr;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use std::convert::TryFrom;
use swap::{alice, alice::swap::AliceState, bitcoin, bob, storage::Database}; use swap::{alice, alice::swap::AliceState, bitcoin, bob, storage::Database};
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; 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 {..})); assert!(matches!(alice_state, AliceState::EncSigLearned {..}));
let alice_db = Database::open(alice_db_datadir.path()).unwrap(); 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() { let resume_state =
assert!(matches!(state, swap::state::Alice::EncSigLearned {..})); 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) = let (mut event_loop_after_restart, event_loop_handle_after_restart) =
testutils::init_alice_event_loop(alice_multiaddr); testutils::init_alice_event_loop(alice_multiaddr);
tokio::spawn(async move { event_loop_after_restart.run().await }); 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( let alice_state = alice::swap::swap(
resume_state, resume_state,
event_loop_handle_after_restart, event_loop_handle_after_restart,