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

View File

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

View File

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

View File

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

View File

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