Use Message4

This commit is contained in:
Franck Royer 2021-01-22 14:21:27 +11:00
parent 124d6f1ebb
commit d2a1937f51
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
13 changed files with 211 additions and 107 deletions

View File

@ -83,7 +83,7 @@ impl From<Alice> for AliceState {
match db_state {
Alice::Started { amounts, state0 } => AliceState::Started { amounts, state0 },
Alice::Negotiated(state3) => AliceState::Negotiated {
channel: None,
bob_peer_id: None,
amounts: SwapAmounts {
btc: state3.btc,
xmr: state3.xmr,
@ -91,7 +91,7 @@ impl From<Alice> for AliceState {
state3: Box::new(state3),
},
Alice::BtcLocked(state3) => AliceState::BtcLocked {
channel: None,
bob_peer_id: None,
amounts: SwapAmounts {
btc: state3.btc,
xmr: state3.xmr,

View File

@ -35,7 +35,7 @@ pub enum AliceToBob {
SwapResponse(alice::SwapResponse),
Message0(Box<alice::Message0>),
Message1(Box<alice::Message1>),
Message2(alice::Message2),
Message2,
}
/// Messages sent from one party to the other.

View File

@ -4,7 +4,6 @@ pub use self::{
event_loop::{EventLoop, EventLoopHandle},
message0::Message0,
message1::Message1,
message2::Message2,
message4::Message4,
state::*,
swap::{run, run_until},
@ -234,9 +233,10 @@ pub enum OutEvent {
channel: ResponseChannel<AliceToBob>,
},
Message2 {
msg: bob::Message2,
channel: ResponseChannel<AliceToBob>,
msg: Box<bob::Message2>,
bob_peer_id: PeerId,
},
Message4,
Message5(Message5),
}
@ -278,7 +278,18 @@ impl From<message1::OutEvent> for OutEvent {
impl From<message2::OutEvent> for OutEvent {
fn from(event: message2::OutEvent) -> Self {
match event {
message2::OutEvent::Msg { msg, channel } => OutEvent::Message2 { msg, channel },
message2::OutEvent::Msg { msg, bob_peer_id } => OutEvent::Message2 {
msg: Box::new(msg),
bob_peer_id,
},
}
}
}
impl From<message4::OutEvent> for OutEvent {
fn from(event: message4::OutEvent) -> Self {
match event {
message4::OutEvent::Msg => OutEvent::Message4,
}
}
}
@ -301,6 +312,7 @@ pub struct Behaviour {
message0: message0::Behaviour,
message1: message1::Behaviour,
message2: message2::Behaviour,
message4: message4::Behaviour,
message5: message5::Behaviour,
}
@ -327,9 +339,9 @@ impl Behaviour {
debug!("Sent Message1");
}
/// Send Message2 to Bob in response to receiving his Message2.
pub fn send_message2(&mut self, channel: ResponseChannel<AliceToBob>, msg: Message2) {
self.message2.send(channel, msg);
debug!("Sent Message2");
/// Send Message4 to Bob.
pub fn send_message4(&mut self, bob: PeerId, msg: Message4) {
self.message4.send(bob, msg);
debug!("Sent Message 4");
}
}

View File

@ -2,7 +2,7 @@ use crate::{
network::{request_response::AliceToBob, transport::SwapTransport, TokioExecutor},
protocol::{
alice,
alice::{Behaviour, OutEvent, SwapResponse},
alice::{Behaviour, Message4, OutEvent, SwapResponse},
bob,
bob::Message5,
},
@ -13,6 +13,7 @@ use libp2p::{
core::Multiaddr, futures::StreamExt, request_response::ResponseChannel, PeerId, Swarm,
};
use tokio::sync::mpsc::{Receiver, Sender};
use tracing::trace;
#[allow(missing_debug_implementations)]
pub struct Channels<T> {
@ -37,14 +38,14 @@ impl<T> Default for Channels<T> {
pub struct EventLoopHandle {
msg0: Receiver<(bob::Message0, ResponseChannel<AliceToBob>)>,
msg1: Receiver<(bob::Message1, ResponseChannel<AliceToBob>)>,
msg2: Receiver<(bob::Message2, ResponseChannel<AliceToBob>)>,
msg2: Receiver<bob::Message2>,
msg5: Receiver<Message5>,
request: Receiver<crate::protocol::alice::swap_response::OutEvent>,
conn_established: Receiver<PeerId>,
send_swap_response: Sender<(ResponseChannel<AliceToBob>, SwapResponse)>,
send_msg0: Sender<(ResponseChannel<AliceToBob>, alice::Message0)>,
send_msg1: Sender<(ResponseChannel<AliceToBob>, alice::Message1)>,
send_msg2: Sender<(ResponseChannel<AliceToBob>, alice::Message2)>,
send_msg4: Sender<(PeerId, Message4)>,
}
impl EventLoopHandle {
@ -69,11 +70,11 @@ impl EventLoopHandle {
.ok_or_else(|| anyhow!("Failed to receive message 1 from Bob"))
}
pub async fn recv_message2(&mut self) -> Result<(bob::Message2, ResponseChannel<AliceToBob>)> {
pub async fn recv_message2(&mut self) -> Result<bob::Message2> {
self.msg2
.recv()
.await
.ok_or_else(|| anyhow!("Failed o receive message 2 from Bob"))
.ok_or_else(|| anyhow!("Failed to receive message 2 from Bob"))
}
pub async fn recv_message5(&mut self) -> Result<Message5> {
@ -122,12 +123,8 @@ impl EventLoopHandle {
Ok(())
}
pub async fn send_message2(
&mut self,
channel: ResponseChannel<AliceToBob>,
msg: alice::Message2,
) -> Result<()> {
let _ = self.send_msg2.send((channel, msg)).await?;
pub async fn send_message4(&mut self, bob: PeerId, msg: Message4) -> Result<()> {
let _ = self.send_msg4.send((bob, msg)).await?;
Ok(())
}
}
@ -137,14 +134,14 @@ pub struct EventLoop {
swarm: libp2p::Swarm<Behaviour>,
msg0: Sender<(bob::Message0, ResponseChannel<AliceToBob>)>,
msg1: Sender<(bob::Message1, ResponseChannel<AliceToBob>)>,
msg2: Sender<(bob::Message2, ResponseChannel<AliceToBob>)>,
msg2: Sender<bob::Message2>,
msg5: Sender<Message5>,
request: Sender<crate::protocol::alice::swap_response::OutEvent>,
conn_established: Sender<PeerId>,
send_swap_response: Receiver<(ResponseChannel<AliceToBob>, SwapResponse)>,
send_msg0: Receiver<(ResponseChannel<AliceToBob>, alice::Message0)>,
send_msg1: Receiver<(ResponseChannel<AliceToBob>, alice::Message1)>,
send_msg2: Receiver<(ResponseChannel<AliceToBob>, alice::Message2)>,
send_msg4: Receiver<(PeerId, Message4)>,
}
impl EventLoop {
@ -172,7 +169,7 @@ impl EventLoop {
let send_swap_response = Channels::new();
let send_msg0 = Channels::new();
let send_msg1 = Channels::new();
let send_msg2 = Channels::new();
let send_msg4 = Channels::new();
let driver = EventLoop {
swarm,
@ -185,7 +182,7 @@ impl EventLoop {
send_swap_response: send_swap_response.receiver,
send_msg0: send_msg0.receiver,
send_msg1: send_msg1.receiver,
send_msg2: send_msg2.receiver,
send_msg4: send_msg4.receiver,
};
let handle = EventLoopHandle {
@ -198,7 +195,7 @@ impl EventLoop {
send_swap_response: send_swap_response.sender,
send_msg0: send_msg0.sender,
send_msg1: send_msg1.sender,
send_msg2: send_msg2.sender,
send_msg4: send_msg4.sender,
};
Ok((driver, handle))
@ -218,9 +215,10 @@ impl EventLoop {
OutEvent::Message1 { msg, channel } => {
let _ = self.msg1.send((msg, channel)).await;
}
OutEvent::Message2 { msg, channel } => {
let _ = self.msg2.send((msg, channel)).await;
OutEvent::Message2 { msg, bob_peer_id : _} => {
let _ = self.msg2.send(*msg).await;
}
OutEvent::Message4 => trace!("Bob ack'd message 4"),
OutEvent::Message5(msg) => {
let _ = self.msg5.send(msg).await;
}
@ -244,9 +242,9 @@ impl EventLoop {
self.swarm.send_message1(channel, msg);
}
},
msg2 = self.send_msg2.next().fuse() => {
if let Some((channel, msg)) = msg2 {
self.swarm.send_message2(channel, msg);
msg4 = self.send_msg4.next().fuse() => {
if let Some((bob_peer_id, msg)) = msg4 {
self.swarm.send_message4(bob_peer_id, msg);
}
},
}

View File

@ -1,17 +1,15 @@
use crate::{
monero,
network::request_response::{AliceToBob, BobToAlice, Codec, Message2Protocol, TIMEOUT},
protocol::bob,
};
use libp2p::{
request_response::{
handler::RequestProtocol, ProtocolSupport, RequestResponse, RequestResponseConfig,
RequestResponseEvent, RequestResponseMessage, ResponseChannel,
RequestResponseEvent, RequestResponseMessage,
},
swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters},
NetworkBehaviour,
NetworkBehaviour, PeerId,
};
use serde::{Deserialize, Serialize};
use std::{
collections::VecDeque,
task::{Context, Poll},
@ -22,18 +20,11 @@ use tracing::{debug, error};
#[derive(Debug)]
pub enum OutEvent {
Msg {
/// Received message from Bob.
msg: bob::Message2,
/// Channel to send back Alice's message 2.
channel: ResponseChannel<AliceToBob>,
bob_peer_id: PeerId,
},
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message2 {
pub tx_lock_proof: monero::TransferProof,
}
/// A `NetworkBehaviour` that represents receiving of message 2 from Bob.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", poll_method = "poll")]
@ -45,11 +36,6 @@ pub struct Behaviour {
}
impl Behaviour {
pub fn send(&mut self, channel: ResponseChannel<AliceToBob>, msg: Message2) {
let msg = AliceToBob::Message2(msg);
self.rr.send_response(channel, msg);
}
fn poll(
&mut self,
_: &mut Context<'_>,
@ -84,15 +70,20 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
fn inject_event(&mut self, event: RequestResponseEvent<BobToAlice, AliceToBob>) {
match event {
RequestResponseEvent::Message {
peer,
message:
RequestResponseMessage::Request {
request, channel, ..
},
..
} => {
if let BobToAlice::Message2(msg) = request {
debug!("Received Message2");
self.events.push_back(OutEvent::Msg { msg, channel });
debug!("Received Message 2");
self.events.push_back(OutEvent::Msg {
msg,
bob_peer_id: peer,
});
// Send back empty response so that the request/response protocol completes.
let _ = self.rr.send_response(channel, AliceToBob::Message2);
}
}
RequestResponseEvent::Message {

View File

@ -8,15 +8,14 @@ use crate::{
},
monero,
monero::CreateWalletForOutput,
network::request_response::AliceToBob,
protocol::{alice, bob, bob::Message5, SwapAmounts},
protocol::{alice, alice::Message4, bob, bob::Message5, SwapAmounts},
};
use anyhow::{anyhow, Context, Result};
use ecdsa_fun::{
adaptor::{Adaptor, EncryptedSignature},
nonce::Deterministic,
};
use libp2p::request_response::ResponseChannel;
use libp2p::PeerId;
use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
@ -30,12 +29,14 @@ pub enum AliceState {
state0: State0,
},
Negotiated {
channel: Option<ResponseChannel<AliceToBob>>,
// TODO: Remove option
bob_peer_id: Option<PeerId>,
amounts: SwapAmounts,
state3: Box<State3>,
},
BtcLocked {
channel: Option<ResponseChannel<AliceToBob>>,
// TODO: Remove option
bob_peer_id: Option<PeerId>,
amounts: SwapAmounts,
state3: Box<State3>,
},
@ -476,8 +477,8 @@ pub struct State5 {
}
impl State5 {
pub fn next_message(&self) -> alice::Message2 {
alice::Message2 {
pub fn next_message(&self) -> Message4 {
Message4 {
tx_lock_proof: self.tx_lock_proof.clone(),
}
}

View File

@ -10,10 +10,9 @@ use crate::{
config::Config,
monero,
monero::Transfer,
network::request_response::AliceToBob,
protocol::{
alice,
alice::{event_loop::EventLoopHandle, SwapResponse},
alice::{event_loop::EventLoopHandle, Message4, SwapResponse},
SwapAmounts,
},
};
@ -23,7 +22,7 @@ use futures::{
future::{select, Either},
pin_mut,
};
use libp2p::request_response::ResponseChannel;
use libp2p::PeerId;
use rand::rngs::OsRng;
use sha2::Sha256;
use std::sync::Arc;
@ -35,11 +34,11 @@ pub async fn negotiate(
xmr_amount: monero::Amount,
event_loop_handle: &mut EventLoopHandle,
config: Config,
) -> Result<(ResponseChannel<AliceToBob>, alice::State3)> {
) -> Result<(PeerId, alice::State3)> {
trace!("Starting negotiate");
// todo: we can move this out, we dont need to timeout here
let _peer_id = timeout(
let bob_peer_id = timeout(
config.bob_time_to_act,
event_loop_handle.recv_conn_established(),
)
@ -73,12 +72,11 @@ pub async fn negotiate(
.send_message1(channel, state2.next_message())
.await?;
let (bob_message2, channel) =
timeout(config.bob_time_to_act, event_loop_handle.recv_message2()).await??;
let bob_message2 = timeout(config.bob_time_to_act, event_loop_handle.recv_message2()).await??;
let state3 = state2.receive(bob_message2)?;
Ok((channel, state3))
Ok((bob_peer_id, state3))
}
// TODO(Franck): Use helper functions from xmr-btc instead of re-writing them
@ -108,7 +106,7 @@ where
}
pub async fn lock_xmr<W>(
channel: ResponseChannel<AliceToBob>,
bob_peer_id: PeerId,
amounts: SwapAmounts,
state3: alice::State3,
event_loop_handle: &mut EventLoopHandle,
@ -134,7 +132,7 @@ where
// Otherwise Alice might publish the lock tx twice!
event_loop_handle
.send_message2(channel, alice::Message2 {
.send_message4(bob_peer_id, Message4 {
tx_lock_proof: transfer_proof,
})
.await?;

View File

@ -91,11 +91,11 @@ async fn run_until_internal(
} else {
match state {
AliceState::Started { amounts, state0 } => {
let (channel, state3) =
let (peer_id, state3) =
negotiate(state0, amounts.xmr, &mut event_loop_handle, config).await?;
let state = AliceState::Negotiated {
channel: Some(channel),
bob_peer_id: Some(peer_id),
amounts,
state3: Box::new(state3),
};
@ -117,11 +117,11 @@ async fn run_until_internal(
}
AliceState::Negotiated {
state3,
channel,
bob_peer_id,
amounts,
} => {
let state = match channel {
Some(channel) => {
let state = match bob_peer_id {
Some(bob_peer_id) => {
let _ = wait_for_locked_bitcoin(
state3.tx_lock.txid(),
bitcoin_wallet.clone(),
@ -130,7 +130,7 @@ async fn run_until_internal(
.await?;
AliceState::BtcLocked {
channel: Some(channel),
bob_peer_id: Some(bob_peer_id),
amounts,
state3,
}
@ -159,14 +159,14 @@ async fn run_until_internal(
.await
}
AliceState::BtcLocked {
channel,
bob_peer_id,
amounts,
state3,
} => {
let state = match channel {
Some(channel) => {
let state = match bob_peer_id {
Some(bob_peer_id) => {
lock_xmr(
channel,
bob_peer_id,
amounts,
*state3.clone(),
&mut event_loop_handle,

View File

@ -31,11 +31,13 @@ pub use self::{
swap::{run, run_until},
swap_request::*,
};
use crate::protocol::alice::Message4;
pub mod event_loop;
mod message0;
mod message1;
mod message2;
mod message4;
mod message5;
pub mod state;
pub mod swap;
@ -210,7 +212,8 @@ pub enum OutEvent {
SwapResponse(alice::SwapResponse),
Message0(Box<alice::Message0>),
Message1(Box<alice::Message1>),
Message2(alice::Message2),
Message2,
Message4(Box<Message4>),
Message5,
}
@ -249,7 +252,15 @@ impl From<message1::OutEvent> for OutEvent {
impl From<message2::OutEvent> for OutEvent {
fn from(event: message2::OutEvent) -> Self {
match event {
message2::OutEvent::Msg(msg) => OutEvent::Message2(msg),
message2::OutEvent::Msg => OutEvent::Message2,
}
}
}
impl From<message4::OutEvent> for OutEvent {
fn from(event: message4::OutEvent) -> Self {
match event {
message4::OutEvent::Msg(msg) => OutEvent::Message4(Box::new(msg)),
}
}
}
@ -272,6 +283,7 @@ pub struct Behaviour {
message0: message0::Behaviour,
message1: message1::Behaviour,
message2: message2::Behaviour,
message4: message4::Behaviour,
message5: message5::Behaviour,
}

View File

@ -3,7 +3,7 @@ use crate::{
network::{transport::SwapTransport, TokioExecutor},
protocol::{
alice,
alice::SwapResponse,
alice::{Message4, SwapResponse},
bob::{self, Behaviour, OutEvent, SwapRequest},
},
};
@ -40,7 +40,7 @@ pub struct EventLoopHandle {
swap_response: Receiver<SwapResponse>,
msg0: Receiver<alice::Message0>,
msg1: Receiver<alice::Message1>,
msg2: Receiver<alice::Message2>,
msg4: Receiver<Message4>,
conn_established: Receiver<PeerId>,
dial_alice: Sender<()>,
send_swap_request: Sender<SwapRequest>,
@ -72,11 +72,11 @@ impl EventLoopHandle {
.ok_or_else(|| anyhow!("Failed to receive message 1 from Alice"))
}
pub async fn recv_message2(&mut self) -> Result<alice::Message2> {
self.msg2
pub async fn recv_message4(&mut self) -> Result<Message4> {
self.msg4
.recv()
.await
.ok_or_else(|| anyhow!("Failed o receive message 2 from Alice"))
.ok_or_else(|| anyhow!("Failed to receive message 4 from Alice"))
}
/// Dials other party and wait for the connection to be established.
@ -126,7 +126,7 @@ pub struct EventLoop {
swap_response: Sender<SwapResponse>,
msg0: Sender<alice::Message0>,
msg1: Sender<alice::Message1>,
msg2: Sender<alice::Message2>,
msg4: Sender<Message4>,
conn_established: Sender<PeerId>,
dial_alice: Receiver<()>,
send_swap_request: Receiver<SwapRequest>,
@ -155,7 +155,7 @@ impl EventLoop {
let swap_response = Channels::new();
let msg0 = Channels::new();
let msg1 = Channels::new();
let msg2 = Channels::new();
let msg4 = Channels::new();
let conn_established = Channels::new();
let dial_alice = Channels::new();
let send_swap_request = Channels::new();
@ -170,7 +170,7 @@ impl EventLoop {
swap_response: swap_response.sender,
msg0: msg0.sender,
msg1: msg1.sender,
msg2: msg2.sender,
msg4: msg4.sender,
conn_established: conn_established.sender,
dial_alice: dial_alice.receiver,
send_swap_request: send_swap_request.receiver,
@ -184,7 +184,7 @@ impl EventLoop {
swap_response: swap_response.receiver,
msg0: msg0.receiver,
msg1: msg1.receiver,
msg2: msg2.receiver,
msg4: msg4.receiver,
conn_established: conn_established.receiver,
dial_alice: dial_alice.sender,
send_swap_request: send_swap_request.sender,
@ -214,8 +214,9 @@ impl EventLoop {
OutEvent::Message1(msg) => {
let _ = self.msg1.send(*msg).await;
}
OutEvent::Message2(msg) => {
let _ = self.msg2.send(msg).await;
OutEvent::Message2 => info!("Alice acknowledged message 2 received"),
OutEvent::Message4(msg) => {
let _ = self.msg4.send(*msg).await;
}
OutEvent::Message5 => info!("Alice acknowledged message 5 received"),
}

View File

@ -1,7 +1,4 @@
use crate::{
network::request_response::{AliceToBob, BobToAlice, Codec, Message2Protocol, TIMEOUT},
protocol::alice,
};
use crate::network::request_response::{AliceToBob, BobToAlice, Codec, Message2Protocol, TIMEOUT};
use ecdsa_fun::Signature;
use libp2p::{
request_response::{
@ -25,9 +22,9 @@ pub struct Message2 {
pub(crate) tx_cancel_sig: Signature,
}
#[derive(Debug)]
#[derive(Clone, Copy, Debug)]
pub enum OutEvent {
Msg(alice::Message2),
Msg,
}
/// A `NetworkBehaviour` that represents sending message 2 to Alice.
@ -87,9 +84,9 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
message: RequestResponseMessage::Response { response, .. },
..
} => {
if let AliceToBob::Message2(msg) = response {
debug!("Received Message2");
self.events.push_back(OutEvent::Msg(msg));
if let AliceToBob::Message2 = response {
debug!("Received Message 2 acknowledgement");
self.events.push_back(OutEvent::Msg);
}
}
RequestResponseEvent::InboundFailure { error, .. } => {

View File

@ -0,0 +1,96 @@
use crate::{
network::request_response::{Message4Protocol, OneShotCodec, Request, Response, TIMEOUT},
protocol::alice::Message4,
};
use libp2p::{
request_response::{
handler::RequestProtocol, ProtocolSupport, RequestResponse, RequestResponseConfig,
RequestResponseEvent, RequestResponseMessage,
},
swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters},
NetworkBehaviour,
};
use std::{
collections::VecDeque,
task::{Context, Poll},
time::Duration,
};
use tracing::{debug, error};
#[derive(Debug)]
pub enum OutEvent {
Msg(Message4),
}
/// A `NetworkBehaviour` that represents receiving of message 4 from Alice.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", poll_method = "poll")]
#[allow(missing_debug_implementations)]
pub struct Behaviour {
rr: RequestResponse<OneShotCodec<Message4Protocol>>,
#[behaviour(ignore)]
events: VecDeque<OutEvent>,
}
impl Behaviour {
fn poll(
&mut self,
_: &mut Context<'_>,
_: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<RequestProtocol<OneShotCodec<Message4Protocol>>, OutEvent>>
{
if let Some(event) = self.events.pop_front() {
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
}
Poll::Pending
}
}
impl Default for Behaviour {
fn default() -> Self {
let timeout = Duration::from_secs(TIMEOUT);
let mut config = RequestResponseConfig::default();
config.set_request_timeout(timeout);
Self {
rr: RequestResponse::new(
OneShotCodec::default(),
vec![(Message4Protocol, ProtocolSupport::Full)],
config,
),
events: Default::default(),
}
}
}
impl NetworkBehaviourEventProcess<RequestResponseEvent<Request, Response>> for Behaviour {
fn inject_event(&mut self, event: RequestResponseEvent<Request, Response>) {
match event {
RequestResponseEvent::Message {
message:
RequestResponseMessage::Request {
request, channel, ..
},
..
} => {
if let Request::Message4(msg) = request {
debug!("Received message 4");
self.events.push_back(OutEvent::Msg(*msg));
// Send back empty response so that the request/response protocol completes.
let _ = self.rr.send_response(channel, Response::Message4);
}
}
RequestResponseEvent::Message {
message: RequestResponseMessage::Response { .. },
..
} => panic!("Bob should not get a Response"),
RequestResponseEvent::InboundFailure { error, .. } => {
error!("Inbound failure: {:?}", error);
}
RequestResponseEvent::OutboundFailure { error, .. } => {
error!("Outbound failure: {:?}", error);
}
}
}
}

View File

@ -130,7 +130,7 @@ where
{
event_loop_handle.dial().await?;
let msg2_watcher = event_loop_handle.recv_message2();
let msg4_watcher = event_loop_handle.recv_message4();
let cancel_timelock_expires =
state3.wait_for_cancel_timelock_to_expire(bitcoin_wallet.as_ref());
@ -143,13 +143,11 @@ where
monero_wallet.inner.block_height().await?;
select! {
msg2 = msg2_watcher => {
let msg2 = msg2?;
msg4 = msg4_watcher => {
let msg4 = msg4?;
BobState::XmrLockProofReceived {
state: state3,
lock_transfer_proof: msg2.tx_lock_proof,
lock_transfer_proof: msg4.tx_lock_proof,
monero_wallet_restore_blockheight
}
},