mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-04-20 16:06:00 -04:00
wip: Segregate negotation and execution setup from swap execution
This commit is contained in:
parent
5a2f82478a
commit
815ef90c9f
@ -14,10 +14,6 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||
pub enum Alice {
|
||||
Started {
|
||||
amounts: SwapAmounts,
|
||||
state0: alice::State0,
|
||||
},
|
||||
Negotiated {
|
||||
state3: alice::State3,
|
||||
#[serde(with = "crate::serde_peer_id")]
|
||||
bob_peer_id: PeerId,
|
||||
@ -54,11 +50,11 @@ pub enum AliceEndState {
|
||||
impl From<&AliceState> for Alice {
|
||||
fn from(alice_state: &AliceState) -> Self {
|
||||
match alice_state {
|
||||
AliceState::Negotiated {
|
||||
AliceState::Started {
|
||||
state3,
|
||||
bob_peer_id,
|
||||
..
|
||||
} => Alice::Negotiated {
|
||||
} => Alice::Started {
|
||||
state3: state3.as_ref().clone(),
|
||||
bob_peer_id: *bob_peer_id,
|
||||
},
|
||||
@ -93,10 +89,6 @@ impl From<&AliceState> for Alice {
|
||||
}
|
||||
AliceState::BtcPunished => Alice::Done(AliceEndState::BtcPunished),
|
||||
AliceState::SafelyAborted => Alice::Done(AliceEndState::SafelyAborted),
|
||||
AliceState::Started { amounts, state0 } => Alice::Started {
|
||||
amounts: *amounts,
|
||||
state0: state0.clone(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,11 +96,10 @@ impl From<&AliceState> for Alice {
|
||||
impl From<Alice> for AliceState {
|
||||
fn from(db_state: Alice) -> Self {
|
||||
match db_state {
|
||||
Alice::Started { amounts, state0 } => AliceState::Started { amounts, state0 },
|
||||
Alice::Negotiated {
|
||||
Alice::Started {
|
||||
state3,
|
||||
bob_peer_id,
|
||||
} => AliceState::Negotiated {
|
||||
} => AliceState::Started {
|
||||
bob_peer_id,
|
||||
amounts: SwapAmounts {
|
||||
btc: state3.btc,
|
||||
@ -186,7 +177,6 @@ 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::XmrLocked(_) => f.write_str("Monero locked"),
|
||||
Alice::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"),
|
||||
|
@ -17,7 +17,6 @@ use anyhow::{bail, Result};
|
||||
use libp2p::{
|
||||
core::Multiaddr, identity::Keypair, request_response::ResponseChannel, NetworkBehaviour, PeerId,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
@ -69,7 +68,11 @@ pub struct Builder {
|
||||
|
||||
enum InitParams {
|
||||
None,
|
||||
New { swap_amounts: SwapAmounts },
|
||||
New {
|
||||
swap_amounts: SwapAmounts,
|
||||
bob_peer_id: PeerId,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
@ -99,19 +102,34 @@ impl Builder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_init_params(self, swap_amounts: SwapAmounts) -> Self {
|
||||
pub fn with_init_params(
|
||||
self,
|
||||
swap_amounts: SwapAmounts,
|
||||
bob_peer_id: PeerId,
|
||||
state3: State3,
|
||||
) -> Self {
|
||||
Self {
|
||||
init_params: InitParams::New { swap_amounts },
|
||||
init_params: InitParams::New {
|
||||
swap_amounts,
|
||||
bob_peer_id,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn build(self) -> Result<(Swap, EventLoop)> {
|
||||
match self.init_params {
|
||||
InitParams::New { swap_amounts } => {
|
||||
let initial_state = self
|
||||
.make_initial_state(swap_amounts.btc, swap_amounts.xmr)
|
||||
.await?;
|
||||
InitParams::New {
|
||||
swap_amounts,
|
||||
bob_peer_id,
|
||||
ref state3,
|
||||
} => {
|
||||
let initial_state = AliceState::Started {
|
||||
bob_peer_id,
|
||||
amounts: swap_amounts,
|
||||
state3: state3.clone(),
|
||||
};
|
||||
|
||||
let (event_loop, event_loop_handle) = self.init_event_loop()?;
|
||||
|
||||
@ -170,31 +188,6 @@ impl Builder {
|
||||
self.listen_address.clone()
|
||||
}
|
||||
|
||||
async fn make_initial_state(
|
||||
&self,
|
||||
btc_to_swap: bitcoin::Amount,
|
||||
xmr_to_swap: monero::Amount,
|
||||
) -> Result<AliceState> {
|
||||
let rng = &mut OsRng;
|
||||
|
||||
let amounts = SwapAmounts {
|
||||
btc: btc_to_swap,
|
||||
xmr: xmr_to_swap,
|
||||
};
|
||||
|
||||
let state0 = State0::new(
|
||||
amounts.btc,
|
||||
amounts.xmr,
|
||||
self.execution_params.bitcoin_cancel_timelock,
|
||||
self.execution_params.bitcoin_punish_timelock,
|
||||
self.bitcoin_wallet.as_ref(),
|
||||
rng,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(AliceState::Started { amounts, state0 })
|
||||
}
|
||||
|
||||
fn init_event_loop(&self) -> Result<(EventLoop, EventLoopHandle)> {
|
||||
let alice_behaviour = Behaviour::default();
|
||||
let alice_transport = build(self.identity.clone())?;
|
||||
|
@ -10,7 +10,7 @@ use libp2p::{
|
||||
core::Multiaddr, futures::FutureExt, request_response::ResponseChannel, PeerId, Swarm,
|
||||
};
|
||||
use tokio::sync::mpsc::{Receiver, Sender};
|
||||
use tracing::{error, trace};
|
||||
use tracing::{debug, error, trace};
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Channels<T> {
|
||||
@ -36,7 +36,6 @@ pub struct EventLoopHandle {
|
||||
done_execution_setup: Receiver<Result<State3>>,
|
||||
recv_encrypted_signature: Receiver<EncryptedSignature>,
|
||||
request: Receiver<crate::protocol::alice::swap_response::OutEvent>,
|
||||
conn_established: Receiver<PeerId>,
|
||||
send_swap_response: Sender<(ResponseChannel<Response>, SwapResponse)>,
|
||||
start_execution_setup: Sender<(PeerId, State0)>,
|
||||
send_transfer_proof: Sender<(PeerId, TransferProof)>,
|
||||
@ -44,13 +43,6 @@ pub struct EventLoopHandle {
|
||||
}
|
||||
|
||||
impl EventLoopHandle {
|
||||
pub async fn recv_conn_established(&mut self) -> Result<PeerId> {
|
||||
self.conn_established
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive connection established from Bob"))
|
||||
}
|
||||
|
||||
pub async fn execution_setup(&mut self, bob_peer_id: PeerId, state0: State0) -> Result<State3> {
|
||||
let _ = self
|
||||
.start_execution_setup
|
||||
@ -109,7 +101,6 @@ pub struct EventLoop {
|
||||
done_execution_setup: Sender<Result<State3>>,
|
||||
recv_encrypted_signature: Sender<EncryptedSignature>,
|
||||
request: Sender<crate::protocol::alice::swap_response::OutEvent>,
|
||||
conn_established: Sender<PeerId>,
|
||||
send_swap_response: Receiver<(ResponseChannel<Response>, SwapResponse)>,
|
||||
send_transfer_proof: Receiver<(PeerId, TransferProof)>,
|
||||
recv_transfer_proof_ack: Sender<()>,
|
||||
@ -135,7 +126,6 @@ impl EventLoop {
|
||||
let done_execution_setup = Channels::new();
|
||||
let recv_encrypted_signature = Channels::new();
|
||||
let request = Channels::new();
|
||||
let conn_established = Channels::new();
|
||||
let send_swap_response = Channels::new();
|
||||
let send_transfer_proof = Channels::new();
|
||||
let recv_transfer_proof_ack = Channels::new();
|
||||
@ -146,7 +136,6 @@ impl EventLoop {
|
||||
done_execution_setup: done_execution_setup.sender,
|
||||
recv_encrypted_signature: recv_encrypted_signature.sender,
|
||||
request: request.sender,
|
||||
conn_established: conn_established.sender,
|
||||
send_swap_response: send_swap_response.receiver,
|
||||
send_transfer_proof: send_transfer_proof.receiver,
|
||||
recv_transfer_proof_ack: recv_transfer_proof_ack.sender,
|
||||
@ -157,7 +146,6 @@ impl EventLoop {
|
||||
done_execution_setup: done_execution_setup.receiver,
|
||||
recv_encrypted_signature: recv_encrypted_signature.receiver,
|
||||
request: request.receiver,
|
||||
conn_established: conn_established.receiver,
|
||||
send_swap_response: send_swap_response.sender,
|
||||
send_transfer_proof: send_transfer_proof.sender,
|
||||
recv_transfer_proof_ack: recv_transfer_proof_ack.receiver,
|
||||
@ -171,8 +159,8 @@ impl EventLoop {
|
||||
tokio::select! {
|
||||
swarm_event = self.swarm.next().fuse() => {
|
||||
match swarm_event {
|
||||
OutEvent::ConnectionEstablished(alice) => {
|
||||
let _ = self.conn_established.send(alice).await;
|
||||
OutEvent::ConnectionEstablished(bob_peer_id) => {
|
||||
debug!("Connection established with {}", bob_peer_id)
|
||||
}
|
||||
OutEvent::ExecutionSetupDone(res) => {
|
||||
let _ = self.done_execution_setup.send(res.map(|state|*state)).await;
|
||||
|
@ -24,10 +24,6 @@ use std::fmt;
|
||||
#[derive(Debug)]
|
||||
pub enum AliceState {
|
||||
Started {
|
||||
amounts: SwapAmounts,
|
||||
state0: State0,
|
||||
},
|
||||
Negotiated {
|
||||
bob_peer_id: PeerId,
|
||||
amounts: SwapAmounts,
|
||||
state3: Box<State3>,
|
||||
@ -69,7 +65,6 @@ impl fmt::Display for AliceState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
AliceState::Started { .. } => write!(f, "started"),
|
||||
AliceState::Negotiated { .. } => write!(f, "negotiated"),
|
||||
AliceState::BtcLocked { .. } => write!(f, "btc is locked"),
|
||||
AliceState::XmrLocked { .. } => write!(f, "xmr is locked"),
|
||||
AliceState::EncSigLearned { .. } => write!(f, "encrypted signature is learned"),
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
monero::Transfer,
|
||||
protocol::{
|
||||
alice,
|
||||
alice::{event_loop::EventLoopHandle, SwapResponse, TransferProof},
|
||||
alice::{event_loop::EventLoopHandle, TransferProof},
|
||||
SwapAmounts,
|
||||
},
|
||||
};
|
||||
@ -26,43 +26,7 @@ use libp2p::PeerId;
|
||||
use sha2::Sha256;
|
||||
use std::sync::Arc;
|
||||
use tokio::time::timeout;
|
||||
use tracing::{info, trace};
|
||||
|
||||
pub async fn negotiate(
|
||||
state0: alice::State0,
|
||||
xmr_amount: monero::Amount,
|
||||
event_loop_handle: &mut EventLoopHandle,
|
||||
execution_params: ExecutionParams,
|
||||
) -> Result<(PeerId, alice::State3)> {
|
||||
trace!("Starting negotiate");
|
||||
|
||||
// todo: we can move this out, we dont need to timeout here
|
||||
let bob_peer_id = timeout(
|
||||
execution_params.bob_time_to_act,
|
||||
event_loop_handle.recv_conn_established(),
|
||||
)
|
||||
.await
|
||||
.context("Failed to receive dial connection from Bob")??;
|
||||
|
||||
let event = timeout(
|
||||
execution_params.bob_time_to_act,
|
||||
event_loop_handle.recv_request(),
|
||||
)
|
||||
.await
|
||||
.context("Failed to receive swap request from Bob")??;
|
||||
|
||||
event_loop_handle
|
||||
.send_swap_response(event.channel, SwapResponse { xmr_amount })
|
||||
.await?;
|
||||
|
||||
let state3 = timeout(
|
||||
execution_params.bob_time_to_act,
|
||||
event_loop_handle.execution_setup(bob_peer_id, state0),
|
||||
)
|
||||
.await??;
|
||||
|
||||
Ok((bob_peer_id, state3))
|
||||
}
|
||||
use tracing::info;
|
||||
|
||||
// TODO(Franck): Use helper functions from xmr-btc instead of re-writing them
|
||||
// here
|
||||
|
@ -17,10 +17,10 @@ use crate::{
|
||||
event_loop::EventLoopHandle,
|
||||
steps::{
|
||||
build_bitcoin_punish_transaction, build_bitcoin_redeem_transaction,
|
||||
extract_monero_private_key, lock_xmr, negotiate,
|
||||
publish_bitcoin_punish_transaction, publish_bitcoin_redeem_transaction,
|
||||
publish_cancel_transaction, wait_for_bitcoin_encrypted_signature,
|
||||
wait_for_bitcoin_refund, wait_for_locked_bitcoin,
|
||||
extract_monero_private_key, lock_xmr, publish_bitcoin_punish_transaction,
|
||||
publish_bitcoin_redeem_transaction, publish_cancel_transaction,
|
||||
wait_for_bitcoin_encrypted_signature, wait_for_bitcoin_refund,
|
||||
wait_for_locked_bitcoin,
|
||||
},
|
||||
AliceState,
|
||||
},
|
||||
@ -91,37 +91,7 @@ async fn run_until_internal(
|
||||
Ok(state)
|
||||
} else {
|
||||
match state {
|
||||
AliceState::Started { amounts, state0 } => {
|
||||
let (bob_peer_id, state3) = negotiate(
|
||||
state0,
|
||||
amounts.xmr,
|
||||
&mut event_loop_handle,
|
||||
execution_params,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let state = AliceState::Negotiated {
|
||||
bob_peer_id,
|
||||
amounts,
|
||||
state3: Box::new(state3),
|
||||
};
|
||||
|
||||
let db_state = (&state).into();
|
||||
db.insert_latest_state(swap_id, database::Swap::Alice(db_state))
|
||||
.await?;
|
||||
run_until_internal(
|
||||
state,
|
||||
is_target_state,
|
||||
event_loop_handle,
|
||||
bitcoin_wallet,
|
||||
monero_wallet,
|
||||
execution_params,
|
||||
swap_id,
|
||||
db,
|
||||
)
|
||||
.await
|
||||
}
|
||||
AliceState::Negotiated {
|
||||
AliceState::Started {
|
||||
state3,
|
||||
bob_peer_id,
|
||||
amounts,
|
||||
|
Loading…
x
Reference in New Issue
Block a user