Bob peer id can be retrieved from the DB

This remove branches where Alice resumes from the DB but cannot contact
Bob.
This commit is contained in:
Franck Royer 2021-01-22 14:56:11 +11:00
parent a910bc2046
commit 33db688e3a
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
6 changed files with 111 additions and 56 deletions

View File

@ -5,6 +5,7 @@ use crate::{
protocol::{alice, alice::AliceState, SwapAmounts}, protocol::{alice, alice::AliceState, SwapAmounts},
}; };
use ::bitcoin::hashes::core::fmt::Display; use ::bitcoin::hashes::core::fmt::Display;
use libp2p::PeerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// Large enum variant is fine because this is only used for database // Large enum variant is fine because this is only used for database
@ -16,8 +17,16 @@ pub enum Alice {
amounts: SwapAmounts, amounts: SwapAmounts,
state0: alice::State0, state0: alice::State0,
}, },
Negotiated(alice::State3), Negotiated {
BtcLocked(alice::State3), state3: alice::State3,
#[serde(with = "crate::serde_peer_id")]
bob_peer_id: PeerId,
},
BtcLocked {
state3: alice::State3,
#[serde(with = "crate::serde_peer_id")]
bob_peer_id: PeerId,
},
XmrLocked(alice::State3), XmrLocked(alice::State3),
EncSigLearned { EncSigLearned {
encrypted_signature: EncryptedSignature, encrypted_signature: EncryptedSignature,
@ -45,8 +54,22 @@ pub enum AliceEndState {
impl From<&AliceState> for Alice { impl From<&AliceState> for Alice {
fn from(alice_state: &AliceState) -> Self { fn from(alice_state: &AliceState) -> Self {
match alice_state { match alice_state {
AliceState::Negotiated { state3, .. } => Alice::Negotiated(state3.as_ref().clone()), AliceState::Negotiated {
AliceState::BtcLocked { state3, .. } => Alice::BtcLocked(state3.as_ref().clone()), state3,
bob_peer_id,
..
} => Alice::Negotiated {
state3: state3.as_ref().clone(),
bob_peer_id: bob_peer_id.clone(),
},
AliceState::BtcLocked {
state3,
bob_peer_id,
..
} => Alice::BtcLocked {
state3: state3.as_ref().clone(),
bob_peer_id: bob_peer_id.clone(),
},
AliceState::XmrLocked { state3 } => Alice::XmrLocked(state3.as_ref().clone()), AliceState::XmrLocked { state3 } => Alice::XmrLocked(state3.as_ref().clone()),
AliceState::EncSigLearned { AliceState::EncSigLearned {
state3, state3,
@ -82,16 +105,22 @@ impl From<Alice> for AliceState {
fn from(db_state: Alice) -> Self { fn from(db_state: Alice) -> Self {
match db_state { match db_state {
Alice::Started { amounts, state0 } => AliceState::Started { amounts, state0 }, Alice::Started { amounts, state0 } => AliceState::Started { amounts, state0 },
Alice::Negotiated(state3) => AliceState::Negotiated { Alice::Negotiated {
bob_peer_id: None, state3,
bob_peer_id,
} => AliceState::Negotiated {
bob_peer_id,
amounts: SwapAmounts { amounts: SwapAmounts {
btc: state3.btc, btc: state3.btc,
xmr: state3.xmr, xmr: state3.xmr,
}, },
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::BtcLocked(state3) => AliceState::BtcLocked { Alice::BtcLocked {
bob_peer_id: None, state3,
bob_peer_id,
} => AliceState::BtcLocked {
bob_peer_id,
amounts: SwapAmounts { amounts: SwapAmounts {
btc: state3.btc, btc: state3.btc,
xmr: state3.xmr, xmr: state3.xmr,
@ -157,8 +186,8 @@ 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 { .. } => write!(f, "Started"), Alice::Started { .. } => write!(f, "Started"),
Alice::Negotiated(_) => f.write_str("Negotiated"), Alice::Negotiated { .. } => f.write_str("Negotiated"),
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::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"),

View File

@ -26,3 +26,4 @@ pub mod seed;
pub mod trace; pub mod trace;
mod fs; mod fs;
mod serde_peer_id;

View File

@ -25,16 +25,18 @@ use tracing::{info, log::LevelFilter};
use uuid::Uuid; use uuid::Uuid;
pub mod bitcoin; pub mod bitcoin;
mod cli;
pub mod config; pub mod config;
pub mod database; pub mod database;
mod fs;
pub mod monero; pub mod monero;
pub mod network; pub mod network;
pub mod protocol; pub mod protocol;
pub mod seed; pub mod seed;
pub mod trace; pub mod trace;
mod cli;
mod fs;
mod serde_peer_id;
#[macro_use] #[macro_use]
extern crate prettytable; extern crate prettytable;

View File

@ -29,14 +29,12 @@ pub enum AliceState {
state0: State0, state0: State0,
}, },
Negotiated { Negotiated {
// TODO: Remove option bob_peer_id: PeerId,
bob_peer_id: Option<PeerId>,
amounts: SwapAmounts, amounts: SwapAmounts,
state3: Box<State3>, state3: Box<State3>,
}, },
BtcLocked { BtcLocked {
// TODO: Remove option bob_peer_id: PeerId,
bob_peer_id: Option<PeerId>,
amounts: SwapAmounts, amounts: SwapAmounts,
state3: Box<State3>, state3: Box<State3>,
}, },

View File

@ -91,11 +91,11 @@ async fn run_until_internal(
} else { } else {
match state { match state {
AliceState::Started { amounts, state0 } => { AliceState::Started { amounts, state0 } => {
let (peer_id, state3) = let (bob_peer_id, state3) =
negotiate(state0, amounts.xmr, &mut event_loop_handle, config).await?; negotiate(state0, amounts.xmr, &mut event_loop_handle, config).await?;
let state = AliceState::Negotiated { let state = AliceState::Negotiated {
bob_peer_id: Some(peer_id), bob_peer_id,
amounts, amounts,
state3: Box::new(state3), state3: Box::new(state3),
}; };
@ -120,27 +120,14 @@ async fn run_until_internal(
bob_peer_id, bob_peer_id,
amounts, amounts,
} => { } => {
let state = match bob_peer_id { let _ =
Some(bob_peer_id) => { wait_for_locked_bitcoin(state3.tx_lock.txid(), bitcoin_wallet.clone(), config)
let _ = wait_for_locked_bitcoin(
state3.tx_lock.txid(),
bitcoin_wallet.clone(),
config,
)
.await?; .await?;
AliceState::BtcLocked { let state = AliceState::BtcLocked {
bob_peer_id: Some(bob_peer_id), bob_peer_id,
amounts, amounts,
state3, state3,
}
}
None => {
tracing::info!("Cannot resume swap from negotiated state, aborting");
// Alice did not lock Xmr yet
AliceState::SafelyAborted
}
}; };
let db_state = (&state).into(); let db_state = (&state).into();
@ -163,26 +150,16 @@ async fn run_until_internal(
amounts, amounts,
state3, state3,
} => { } => {
let state = match bob_peer_id { lock_xmr(
Some(bob_peer_id) => { bob_peer_id,
lock_xmr( amounts,
bob_peer_id, *state3.clone(),
amounts, &mut event_loop_handle,
*state3.clone(), monero_wallet.clone(),
&mut event_loop_handle, )
monero_wallet.clone(), .await?;
)
.await?;
AliceState::XmrLocked { state3 } let state = AliceState::XmrLocked { state3 };
}
None => {
tracing::info!("Cannot resume swap from BTC locked state, aborting");
// Alice did not lock Xmr yet
AliceState::SafelyAborted
}
};
let db_state = (&state).into(); let db_state = (&state).into();
db.insert_latest_state(swap_id, database::Swap::Alice(db_state)) db.insert_latest_state(swap_id, database::Swap::Alice(db_state))

48
swap/src/serde_peer_id.rs Normal file
View File

@ -0,0 +1,48 @@
//! A serde module that defines how we want to serialize PeerIds on the
//! HTTP-API.
use libp2p::PeerId;
use serde::{de::Error, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(peer_id: &PeerId, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = peer_id.to_string();
serializer.serialize_str(&string)
}
#[allow(dead_code)]
pub fn deserialize<'de, D>(deserializer: D) -> Result<PeerId, D::Error>
where
D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
let peer_id = string.parse().map_err(D::Error::custom)?;
Ok(peer_id)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Serialize;
use spectral::prelude::*;
#[derive(Serialize)]
struct SerializablePeerId(#[serde(with = "super")] PeerId);
#[test]
fn maker_id_serializes_as_expected() {
let peer_id = SerializablePeerId(
"QmfUfpC2frwFvcDzpspnfZitHt5wct6n4kpG5jzgRdsxkY"
.parse()
.unwrap(),
);
let got = serde_json::to_string(&peer_id).expect("failed to serialize peer id");
assert_that(&got)
.is_equal_to(r#""QmfUfpC2frwFvcDzpspnfZitHt5wct6n4kpG5jzgRdsxkY""#.to_string());
}
}