405: Concurrent swaps with same peer r=da-kami a=da-kami

Fixes #367 

- [x] Concurrent swaps with same peer

Not sure how much more time I should invest into this. We could just merge the current state and then do improvements on top...?

Improvements:

- [x] Think `// TODO: Remove unnecessary swap-id check` through and remove it
- [x] Add concurrent swap test, multiple swaps with same Bob
- [ ] Save swap messages without matching swap in execution in the database
- [ ] Assert the balances in the new concurrent swap tests
- [ ] ~~Add concurrent swap test, multiple swaps with different Bobs~~
- [ ] ~~Send swap-id in separate message, not on top of `Message0`~~

Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
bors[bot] 2021-04-13 08:50:44 +00:00 committed by GitHub
commit 19766b9759
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 456 additions and 127 deletions

View file

@ -79,8 +79,9 @@ async fn main() -> Result<()> {
let mut swarm = swarm::new::<Behaviour>(&seed)?;
swarm.add_address(alice_peer_id, alice_multiaddr);
let swap_id = Uuid::new_v4();
let (event_loop, mut event_loop_handle) =
EventLoop::new(swarm, alice_peer_id, bitcoin_wallet.clone())?;
EventLoop::new(swap_id, swarm, alice_peer_id, bitcoin_wallet.clone())?;
let event_loop = tokio::spawn(event_loop.run());
let send_bitcoin = determine_btc_to_swap(
@ -174,7 +175,7 @@ async fn main() -> Result<()> {
swarm.add_address(alice_peer_id, alice_multiaddr);
let (event_loop, event_loop_handle) =
EventLoop::new(swarm, alice_peer_id, bitcoin_wallet.clone())?;
EventLoop::new(swap_id, swarm, alice_peer_id, bitcoin_wallet.clone())?;
let handle = tokio::spawn(event_loop.run());
let swap = Builder::new(

View file

@ -5,6 +5,7 @@ use libp2p::request_response::{
RequestResponseMessage,
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type OutEvent = RequestResponseEvent<Request, ()>;
@ -19,6 +20,7 @@ impl ProtocolName for EncryptedSignatureProtocol {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Request {
pub swap_id: Uuid,
pub tx_redeem_encsig: crate::bitcoin::EncryptedSignature,
}

View file

@ -6,6 +6,7 @@ use libp2p::request_response::{
RequestResponseMessage,
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type OutEvent = RequestResponseEvent<Request, ()>;
@ -20,6 +21,7 @@ impl ProtocolName for TransferProofProtocol {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Request {
pub swap_id: Uuid,
pub tx_lock_proof: monero::TransferProof,
}

View file

@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
use sha2::Sha256;
use sigma_fun::ext::dl_secp256k1_ed25519_eq::{CrossCurveDLEQ, CrossCurveDLEQProof};
use sigma_fun::HashTranscript;
use uuid::Uuid;
pub mod alice;
pub mod bob;
@ -18,14 +19,9 @@ pub static CROSS_CURVE_PROOF_SYSTEM: Lazy<
)
});
#[derive(Debug, Copy, Clone)]
pub struct StartingBalances {
pub xmr: monero::Amount,
pub btc: bitcoin::Amount,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message0 {
swap_id: Uuid,
B: bitcoin::PublicKey,
S_b_monero: monero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey,

View file

@ -6,6 +6,7 @@ use libp2p::request_response::{
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
};
use libp2p::{NetworkBehaviour, PeerId};
use uuid::Uuid;
#[derive(Debug)]
pub enum OutEvent {
@ -20,6 +21,7 @@ pub enum OutEvent {
},
ExecutionSetupDone {
bob_peer_id: PeerId,
swap_id: Uuid,
state3: Box<State3>,
},
TransferProofAcknowledged {
@ -157,9 +159,11 @@ impl From<execution_setup::OutEvent> for OutEvent {
match event {
Done {
bob_peer_id,
swap_id,
state3,
} => OutEvent::ExecutionSetupDone {
bob_peer_id,
swap_id,
state3: Box::new(state3),
},
Failure { peer, error } => OutEvent::Failure { peer, error },

View file

@ -3,7 +3,7 @@ use crate::database::Database;
use crate::env::Config;
use crate::monero::BalanceTooLow;
use crate::network::quote::BidQuote;
use crate::network::{encrypted_signature, spot_price, transfer_proof};
use crate::network::{spot_price, transfer_proof};
use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State0, State3, Swap};
use crate::{bitcoin, kraken, monero};
use anyhow::{bail, Context, Result};
@ -43,16 +43,15 @@ pub struct EventLoop<RS> {
swap_sender: mpsc::Sender<Swap>,
/// Stores a sender per peer for incoming [`EncryptedSignature`]s.
recv_encrypted_signature:
HashMap<PeerId, bmrng::RequestSender<encrypted_signature::Request, ()>>,
/// Stores incoming [`EncryptedSignature`]s per swap.
recv_encrypted_signature: HashMap<Uuid, bmrng::RequestSender<bitcoin::EncryptedSignature, ()>>,
inflight_encrypted_signatures: FuturesUnordered<BoxFuture<'static, ResponseChannel<()>>>,
send_transfer_proof: FuturesUnordered<OutgoingTransferProof>,
/// Tracks [`transfer_proof::Request`]s which could not yet be sent because
/// we are currently disconnected from the peer.
buffered_transfer_proofs: HashMap<PeerId, (transfer_proof::Request, bmrng::Responder<()>)>,
buffered_transfer_proofs: HashMap<PeerId, Vec<(transfer_proof::Request, bmrng::Responder<()>)>>,
/// Tracks [`transfer_proof::Request`]s which are currently inflight and
/// awaiting an acknowledgement.
@ -120,7 +119,7 @@ where
}
};
let handle = self.new_handle(peer_id);
let handle = self.new_handle(peer_id, swap_id);
let swap = Swap {
event_loop_handle: handle,
@ -186,25 +185,26 @@ where
tracing::debug!(%peer, "Failed to respond with quote");
}
}
SwarmEvent::Behaviour(OutEvent::ExecutionSetupDone{bob_peer_id, state3}) => {
let _ = self.handle_execution_setup_done(bob_peer_id, *state3).await;
SwarmEvent::Behaviour(OutEvent::ExecutionSetupDone{bob_peer_id, swap_id, state3}) => {
let _ = self.handle_execution_setup_done(bob_peer_id, swap_id, *state3).await;
}
SwarmEvent::Behaviour(OutEvent::TransferProofAcknowledged { peer, id }) => {
tracing::trace!(%peer, "Bob acknowledged transfer proof");
tracing::debug!(%peer, "Bob acknowledged transfer proof");
if let Some(responder) = self.inflight_transfer_proofs.remove(&id) {
let _ = responder.respond(());
}
}
SwarmEvent::Behaviour(OutEvent::EncryptedSignatureReceived{ msg, channel, peer }) => {
let sender = match self.recv_encrypted_signature.remove(&peer) {
let sender = match self.recv_encrypted_signature.remove(&msg.swap_id) {
Some(sender) => sender,
None => {
// TODO: Don't just drop encsig if we currently don't have a running swap for it, save in db
tracing::warn!(%peer, "No sender for encrypted signature, maybe already handled?");
continue;
}
};
let mut responder = match sender.send(*msg).await {
let mut responder = match sender.send(msg.tx_redeem_encsig).await {
Ok(responder) => responder,
Err(_) => {
tracing::warn!(%peer, "Failed to relay encrypted signature to swap");
@ -225,11 +225,13 @@ where
SwarmEvent::ConnectionEstablished { peer_id: peer, endpoint, .. } => {
tracing::debug!(%peer, address = %endpoint.get_remote_address(), "New connection established");
if let Some((transfer_proof, responder)) = self.buffered_transfer_proofs.remove(&peer) {
tracing::debug!(%peer, "Found buffered transfer proof for peer");
if let Some(transfer_proofs) = self.buffered_transfer_proofs.remove(&peer) {
for (transfer_proof, responder) in transfer_proofs {
tracing::debug!(%peer, "Found buffered transfer proof for peer");
let id = self.swarm.transfer_proof.send_request(&peer, transfer_proof);
self.inflight_transfer_proofs.insert(id, responder);
let id = self.swarm.transfer_proof.send_request(&peer, transfer_proof);
self.inflight_transfer_proofs.insert(id, responder);
}
}
}
SwarmEvent::IncomingConnectionError { send_back_addr: address, error, .. } => {
@ -253,15 +255,15 @@ where
Some(Ok((peer, transfer_proof, responder))) => {
if !self.swarm.transfer_proof.is_connected(&peer) {
tracing::warn!(%peer, "No active connection to peer, buffering transfer proof");
self.buffered_transfer_proofs.insert(peer, (transfer_proof, responder));
self.buffered_transfer_proofs.entry(peer).or_insert_with(Vec::new).push((transfer_proof, responder));
continue;
}
let id = self.swarm.transfer_proof.send_request(&peer, transfer_proof);
self.inflight_transfer_proofs.insert(id, responder);
},
Some(Err(_)) => {
tracing::debug!("A swap stopped without sending a transfer proof");
Some(Err(e)) => {
tracing::debug!("A swap stopped without sending a transfer proof: {:#}", e);
}
None => {
unreachable!("stream of transfer proof receivers must never terminate")
@ -317,9 +319,13 @@ where
})
}
async fn handle_execution_setup_done(&mut self, bob_peer_id: PeerId, state3: State3) {
let swap_id = Uuid::new_v4();
let handle = self.new_handle(bob_peer_id);
async fn handle_execution_setup_done(
&mut self,
bob_peer_id: PeerId,
swap_id: Uuid,
state3: State3,
) {
let handle = self.new_handle(bob_peer_id, swap_id);
let initial_state = AliceState::Started {
state3: Box::new(state3),
@ -335,7 +341,7 @@ where
swap_id,
};
// TODO: Consider adding separate components for start/rsume of swaps
// TODO: Consider adding separate components for start/resume of swaps
// swaps save peer id so we can resume
match self.db.insert_peer_id(swap_id, bob_peer_id).await {
@ -352,17 +358,24 @@ where
/// Create a new [`EventLoopHandle`] that is scoped for communication with
/// the given peer.
fn new_handle(&mut self, peer: PeerId) -> EventLoopHandle {
fn new_handle(&mut self, peer: PeerId, swap_id: Uuid) -> EventLoopHandle {
// we deliberately don't put timeouts on these channels because the swap always
// races these futures against a timelock
let (transfer_proof_sender, mut transfer_proof_receiver) = bmrng::channel(1);
let encrypted_signature = bmrng::channel(1);
self.recv_encrypted_signature
.insert(peer, encrypted_signature.0);
.insert(swap_id, encrypted_signature.0);
self.send_transfer_proof.push(
async move {
let (request, responder) = transfer_proof_receiver.recv().await?;
let (transfer_proof, responder) = transfer_proof_receiver.recv().await?;
let request = transfer_proof::Request {
swap_id,
tx_lock_proof: transfer_proof,
};
Ok((peer, request, responder))
}
@ -440,13 +453,13 @@ impl LatestRate for KrakenRate {
#[derive(Debug)]
pub struct EventLoopHandle {
recv_encrypted_signature: Option<bmrng::RequestReceiver<encrypted_signature::Request, ()>>,
send_transfer_proof: Option<bmrng::RequestSender<transfer_proof::Request, ()>>,
recv_encrypted_signature: Option<bmrng::RequestReceiver<bitcoin::EncryptedSignature, ()>>,
send_transfer_proof: Option<bmrng::RequestSender<monero::TransferProof, ()>>,
}
impl EventLoopHandle {
pub async fn recv_encrypted_signature(&mut self) -> Result<bitcoin::EncryptedSignature> {
let (request, responder) = self
let (tx_redeem_encsig, responder) = self
.recv_encrypted_signature
.take()
.context("Encrypted signature was already received")?
@ -457,14 +470,14 @@ impl EventLoopHandle {
.respond(())
.context("Failed to acknowledge receipt of encrypted signature")?;
Ok(request.tx_redeem_encsig)
Ok(tx_redeem_encsig)
}
pub async fn send_transfer_proof(&mut self, msg: monero::TransferProof) -> Result<()> {
self.send_transfer_proof
.take()
.context("Transfer proof was already sent")?
.send_receive(transfer_proof::Request { tx_lock_proof: msg })
.send_receive(msg)
.await
.context("Failed to send transfer proof")?;

View file

@ -4,18 +4,27 @@ use crate::protocol::{Message0, Message2, Message4};
use anyhow::{Context, Error};
use libp2p::PeerId;
use libp2p_async_await::BehaviourOutEvent;
use uuid::Uuid;
#[derive(Debug)]
pub enum OutEvent {
Done { bob_peer_id: PeerId, state3: State3 },
Failure { peer: PeerId, error: Error },
Done {
bob_peer_id: PeerId,
swap_id: Uuid,
state3: State3,
},
Failure {
peer: PeerId,
error: Error,
},
}
impl From<BehaviourOutEvent<(PeerId, State3), (), Error>> for OutEvent {
fn from(event: BehaviourOutEvent<(PeerId, State3), (), Error>) -> Self {
impl From<BehaviourOutEvent<(PeerId, (Uuid, State3)), (), Error>> for OutEvent {
fn from(event: BehaviourOutEvent<(PeerId, (Uuid, State3)), (), Error>) -> Self {
match event {
BehaviourOutEvent::Inbound(_, Ok((bob_peer_id, state3))) => OutEvent::Done {
BehaviourOutEvent::Inbound(_, Ok((bob_peer_id, (swap_id, state3)))) => OutEvent::Done {
bob_peer_id,
swap_id,
state3,
},
BehaviourOutEvent::Inbound(peer, Err(e)) => OutEvent::Failure { peer, error: e },
@ -27,7 +36,7 @@ impl From<BehaviourOutEvent<(PeerId, State3), (), Error>> for OutEvent {
#[derive(libp2p::NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)]
pub struct Behaviour {
inner: libp2p_async_await::Behaviour<(PeerId, State3), (), anyhow::Error>,
inner: libp2p_async_await::Behaviour<(PeerId, (Uuid, State3)), (), anyhow::Error>,
}
impl Default for Behaviour {
@ -45,7 +54,7 @@ impl Behaviour {
let message0 =
serde_cbor::from_slice::<Message0>(&substream.read_message(BUF_SIZE).await?)
.context("Failed to deserialize message0")?;
let state1 = state0.receive(message0)?;
let (swap_id, state1) = state0.receive(message0)?;
substream
.write_message(
@ -73,7 +82,7 @@ impl Behaviour {
.context("Failed to deserialize message4")?;
let state3 = state2.receive(message4)?;
Ok((bob, state3))
Ok((bob, (swap_id, state3)))
})
}
}

View file

@ -13,6 +13,7 @@ use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof;
use std::fmt;
use uuid::Uuid;
#[derive(Debug)]
pub enum AliceState {
@ -146,7 +147,7 @@ impl State0 {
})
}
pub fn receive(self, msg: Message0) -> Result<State1> {
pub fn receive(self, msg: Message0) -> Result<(Uuid, State1)> {
let valid = CROSS_CURVE_PROOF_SYSTEM.verify(
&msg.dleq_proof_s_b,
(
@ -164,7 +165,7 @@ impl State0 {
let v = self.v_a + msg.v_b;
Ok(State1 {
Ok((msg.swap_id, State1 {
a: self.a,
B: msg.B,
s_a: self.s_a,
@ -182,7 +183,7 @@ impl State0 {
refund_address: msg.refund_address,
redeem_address: self.redeem_address,
punish_address: self.punish_address,
})
}))
}
}

View file

@ -5,7 +5,6 @@ use crate::env::Config;
use crate::protocol::alice;
use crate::protocol::alice::event_loop::EventLoopHandle;
use crate::protocol::alice::AliceState;
use crate::protocol::alice::AliceState::XmrLockTransferProofSent;
use crate::{bitcoin, database, monero};
use anyhow::{bail, Context, Result};
use tokio::select;
@ -17,7 +16,7 @@ pub async fn run(swap: alice::Swap) -> Result<AliceState> {
run_until(swap, |_| false).await
}
#[tracing::instrument(name = "swap", skip(swap,exit_early), fields(id = %swap.swap_id))]
#[tracing::instrument(name = "swap", skip(swap,exit_early), fields(id = %swap.swap_id), err)]
pub async fn run_until(
mut swap: alice::Swap,
exit_early: fn(&AliceState) -> bool,
@ -130,7 +129,7 @@ async fn next_state(
result = event_loop_handle.send_transfer_proof(transfer_proof.clone()) => {
result?;
XmrLockTransferProofSent {
AliceState::XmrLockTransferProofSent {
monero_wallet_restore_blockheight,
transfer_proof,
state3,

View file

@ -1,6 +1,6 @@
use crate::bitcoin::EncryptedSignature;
use crate::network::quote::BidQuote;
use crate::network::{encrypted_signature, spot_price, transfer_proof};
use crate::network::{encrypted_signature, spot_price};
use crate::protocol::bob::{Behaviour, OutEvent, State0, State2};
use crate::{bitcoin, monero};
use anyhow::{Context, Result};
@ -12,9 +12,11 @@ use libp2p::{PeerId, Swarm};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use uuid::Uuid;
#[allow(missing_debug_implementations)]
pub struct EventLoop {
swap_id: Uuid,
swarm: libp2p::Swarm<Behaviour>,
bitcoin_wallet: Arc<bitcoin::Wallet>,
alice_peer_id: PeerId,
@ -22,7 +24,7 @@ pub struct EventLoop {
// these streams represents outgoing requests that we have to make
quote_requests: bmrng::RequestReceiverStream<(), BidQuote>,
spot_price_requests: bmrng::RequestReceiverStream<spot_price::Request, spot_price::Response>,
encrypted_signature_requests: bmrng::RequestReceiverStream<encrypted_signature::Request, ()>,
encrypted_signatures: bmrng::RequestReceiverStream<EncryptedSignature, ()>,
execution_setup_requests: bmrng::RequestReceiverStream<State0, Result<State2>>,
// these represents requests that are currently in-flight.
@ -34,7 +36,7 @@ pub struct EventLoop {
inflight_execution_setup: Option<bmrng::Responder<Result<State2>>>,
/// The sender we will use to relay incoming transfer proofs.
transfer_proof: bmrng::RequestSender<transfer_proof::Request, ()>,
transfer_proof: bmrng::RequestSender<monero::TransferProof, ()>,
/// The future representing the successful handling of an incoming transfer
/// proof.
///
@ -47,6 +49,7 @@ pub struct EventLoop {
impl EventLoop {
pub fn new(
swap_id: Uuid,
swarm: Swarm<Behaviour>,
alice_peer_id: PeerId,
bitcoin_wallet: Arc<bitcoin::Wallet>,
@ -58,12 +61,13 @@ impl EventLoop {
let quote = bmrng::channel_with_timeout(1, Duration::from_secs(30));
let event_loop = EventLoop {
swap_id,
swarm,
alice_peer_id,
bitcoin_wallet,
execution_setup_requests: execution_setup.1.into(),
transfer_proof: transfer_proof.0,
encrypted_signature_requests: encrypted_signature.1.into(),
encrypted_signatures: encrypted_signature.1.into(),
spot_price_requests: spot_price.1.into(),
quote_requests: quote.1.into(),
inflight_spot_price_requests: HashMap::default(),
@ -108,10 +112,20 @@ impl EventLoop {
}
}
SwarmEvent::Behaviour(OutEvent::TransferProofReceived { msg, channel }) => {
let mut responder = match self.transfer_proof.send(*msg).await {
if msg.swap_id != self.swap_id {
// TODO: Save unexpected transfer proofs in the database and check for messages in the database when handling swaps
tracing::warn!("Received unexpected transfer proof for swap {} while running swap {}. This transfer proof will be ignored.", msg.swap_id, self.swap_id);
// When receiving a transfer proof that is unexpected we still have to acknowledge that it was received
let _ = self.swarm.transfer_proof.send_response(channel, ());
continue;
}
let mut responder = match self.transfer_proof.send(msg.tx_lock_proof).await {
Ok(responder) => responder,
Err(_) => {
tracing::warn!("Failed to pass on transfer proof");
Err(e) => {
tracing::warn!("Failed to pass on transfer proof: {:#}", e);
continue;
}
};
@ -180,7 +194,12 @@ impl EventLoop {
self.swarm.execution_setup.run(self.alice_peer_id, request, self.bitcoin_wallet.clone());
self.inflight_execution_setup = Some(responder);
},
Some((request, responder)) = self.encrypted_signature_requests.next().fuse(), if self.is_connected_to_alice() => {
Some((tx_redeem_encsig, responder)) = self.encrypted_signatures.next().fuse(), if self.is_connected_to_alice() => {
let request = encrypted_signature::Request {
swap_id: self.swap_id,
tx_redeem_encsig
};
let id = self.swarm.encrypted_signature.send_request(&self.alice_peer_id, request);
self.inflight_encrypted_signature_requests.insert(id, responder);
},
@ -202,8 +221,8 @@ impl EventLoop {
#[derive(Debug)]
pub struct EventLoopHandle {
execution_setup: bmrng::RequestSender<State0, Result<State2>>,
transfer_proof: bmrng::RequestReceiver<transfer_proof::Request, ()>,
encrypted_signature: bmrng::RequestSender<encrypted_signature::Request, ()>,
transfer_proof: bmrng::RequestReceiver<monero::TransferProof, ()>,
encrypted_signature: bmrng::RequestSender<EncryptedSignature, ()>,
spot_price: bmrng::RequestSender<spot_price::Request, spot_price::Response>,
quote: bmrng::RequestSender<(), BidQuote>,
}
@ -213,8 +232,8 @@ impl EventLoopHandle {
self.execution_setup.send_receive(state0).await?
}
pub async fn recv_transfer_proof(&mut self) -> Result<transfer_proof::Request> {
let (request, responder) = self
pub async fn recv_transfer_proof(&mut self) -> Result<monero::TransferProof> {
let (transfer_proof, responder) = self
.transfer_proof
.recv()
.await
@ -223,7 +242,7 @@ impl EventLoopHandle {
.respond(())
.context("Failed to acknowledge receipt of transfer proof")?;
Ok(request)
Ok(transfer_proof)
}
pub async fn request_spot_price(&mut self, btc: bitcoin::Amount) -> Result<monero::Amount> {
@ -244,7 +263,7 @@ impl EventLoopHandle {
) -> Result<()> {
Ok(self
.encrypted_signature
.send_receive(encrypted_signature::Request { tx_redeem_encsig })
.send_receive(tx_redeem_encsig)
.await?)
}
}

View file

@ -17,6 +17,7 @@ use serde::{Deserialize, Serialize};
use sha2::Sha256;
use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof;
use std::fmt;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub enum BobState {
@ -69,6 +70,7 @@ impl fmt::Display for BobState {
#[derive(Clone, Debug, PartialEq)]
pub struct State0 {
swap_id: Uuid,
b: bitcoin::SecretKey,
s_b: monero::Scalar,
S_b_monero: monero::PublicKey,
@ -84,7 +86,9 @@ pub struct State0 {
}
impl State0 {
#[allow(clippy::too_many_arguments)]
pub fn new<R: RngCore + CryptoRng>(
swap_id: Uuid,
rng: &mut R,
btc: bitcoin::Amount,
xmr: monero::Amount,
@ -101,6 +105,7 @@ impl State0 {
let (dleq_proof_s_b, (S_b_bitcoin, S_b_monero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_b, rng);
Self {
swap_id,
b,
s_b,
v_b,
@ -120,6 +125,7 @@ impl State0 {
pub fn next_message(&self) -> Message0 {
Message0 {
swap_id: self.swap_id,
B: self.b.public(),
S_b_monero: self.S_b_monero,
S_b_bitcoin: self.S_b_bitcoin,

View file

@ -68,6 +68,7 @@ async fn next_state(
let bitcoin_refund_address = bitcoin_wallet.new_address().await?;
let state2 = request_price_and_setup(
swap_id,
btc_amount,
event_loop_handle,
env_config,
@ -106,7 +107,7 @@ async fn next_state(
select! {
transfer_proof = transfer_proof_watcher => {
let transfer_proof = transfer_proof?.tx_lock_proof;
let transfer_proof = transfer_proof?;
tracing::info!(txid = %transfer_proof.tx_hash(), "Alice locked Monero");
@ -259,6 +260,7 @@ async fn next_state(
}
pub async fn request_price_and_setup(
swap_id: Uuid,
btc: bitcoin::Amount,
event_loop_handle: &mut EventLoopHandle,
env_config: &Config,
@ -269,6 +271,7 @@ pub async fn request_price_and_setup(
tracing::info!("Spot price for {} is {}", btc, xmr);
let state0 = State0::new(
swap_id,
&mut OsRng,
btc,
xmr,