Bubble up an event when Bob receives message 3 response

Before this patch Bob is not sending message 3. This is because we are not
polling Bob's swarm correctly. To fix it we can just mimic the other NB's and
bubble up an event when Bob receives message 3 response from Alice, this way we
can `await` upon this event which triggers polling, making Bob's swarm send the
message.
This commit is contained in:
Tobin C. Harding 2020-10-30 09:26:52 +11:00 committed by Lucas Soriano del Pino
parent a37f43a1ba
commit 4d4acde476
6 changed files with 49 additions and 16 deletions

View File

@ -78,10 +78,15 @@ pub async fn swap(
#[derive(Debug)]
struct UnexpectedMessage;
tracing::debug!("Receiving bitcoin redeem encsig");
(|| async {
let mut guard = self.swarm.lock().await;
let encsig = match guard.next().await {
OutEvent::Message3(msg) => msg.tx_redeem_encsig,
OutEvent::Message3(msg) => {
tracing::debug!("Got redeem encsig from Bob");
msg.tx_redeem_encsig
}
other => {
warn!("Expected Bob's Message3, got: {:?}", other);
return Err(backoff::Error::Transient(UnexpectedMessage));

View File

@ -73,6 +73,7 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
..
} => {
if let BobToAlice::Message3(msg) = request {
tracing::debug!("Alice: got message 3 from Bob");
self.events.push_back(OutEvent::Msg(msg));
// Send back empty response so that the request/response protocol completes.
self.rr.send_response(channel, AliceToBob::Message3);

View File

@ -29,7 +29,7 @@ use crate::{
peer_tracker::{self, PeerTracker},
transport, TokioExecutor,
},
Cmd, Never, Rsp, SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
Cmd, Rsp, SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
};
use xmr_btc::{
alice,
@ -64,7 +64,10 @@ pub async fn swap(
(|| async {
let proof = match future.clone().await {
OutEvent::Message2(msg) => msg.tx_lock_proof,
OutEvent::Message2(msg) => {
debug!("Got transfer proof from Alice");
msg.tx_lock_proof
}
other => {
warn!("Expected Alice's Message2, got: {:?}", other);
return Err(backoff::Error::Transient(UnexpectedMessage));
@ -164,7 +167,14 @@ pub async fn swap(
}
GeneratorState::Yielded(bob::Action::SendBtcRedeemEncsig(tx_redeem_encsig)) => {
let mut guard = network.as_ref().lock().await;
debug!("Bob: sending message 3");
guard.0.send_message3(alice.clone(), tx_redeem_encsig);
match guard.0.next().shared().await {
OutEvent::Message3 => {
debug!("Got message 3 response from Alice");
}
other => panic!("unexpected event: {:?}", other),
};
}
GeneratorState::Yielded(bob::Action::CreateXmrWalletForOutput {
spend_key,
@ -227,6 +237,7 @@ pub enum OutEvent {
Message0(alice::Message0),
Message1(alice::Message1),
Message2(alice::Message2),
Message3,
}
impl From<peer_tracker::OutEvent> for OutEvent {
@ -271,9 +282,11 @@ impl From<message2::OutEvent> for OutEvent {
}
}
impl From<Never> for OutEvent {
fn from(_: Never) -> Self {
panic!("not ever")
impl From<message3::OutEvent> for OutEvent {
fn from(event: message3::OutEvent) -> Self {
match event {
message3::OutEvent::Msg => OutEvent::Message3,
}
}
}

View File

@ -7,38 +7,46 @@ use libp2p::{
NetworkBehaviour, PeerId,
};
use std::{
collections::VecDeque,
task::{Context, Poll},
time::Duration,
};
use tracing::{debug, error};
use tracing::error;
use crate::{
network::request_response::{AliceToBob, BobToAlice, Codec, Message3Protocol, TIMEOUT},
Never,
};
use crate::network::request_response::{AliceToBob, BobToAlice, Codec, Message3Protocol, TIMEOUT};
use xmr_btc::bob;
#[derive(Debug)]
pub enum OutEvent {
Msg,
}
/// A `NetworkBehaviour` that represents sending message 3 to Alice.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "Never", poll_method = "poll")]
#[behaviour(out_event = "OutEvent", poll_method = "poll")]
#[allow(missing_debug_implementations)]
pub struct Message3 {
rr: RequestResponse<Codec<Message3Protocol>>,
#[behaviour(ignore)]
events: VecDeque<OutEvent>,
}
impl Message3 {
pub fn send(&mut self, alice: PeerId, msg: bob::Message3) {
let msg = BobToAlice::Message3(msg);
tracing::debug!("sending ...");
let _id = self.rr.send_request(&alice, msg);
}
// TODO: Do we need a custom implementation if we are not bubbling any out
// events?
fn poll(
&mut self,
_: &mut Context<'_>,
_: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<Message3Protocol>>, Never>> {
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<Message3Protocol>>, OutEvent>> {
if let Some(event) = self.events.pop_front() {
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
}
Poll::Pending
}
}
@ -55,6 +63,7 @@ impl Default for Message3 {
vec![(Message3Protocol, ProtocolSupport::Full)],
config,
),
events: Default::default(),
}
}
}
@ -71,7 +80,8 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
..
} => {
if let AliceToBob::Message3 = response {
debug!("Alice correctly responded to message 3");
self.events.push_back(OutEvent::Msg);
tracing::debug!("Alice correctly responded to message 3");
}
}
RequestResponseEvent::InboundFailure { error, .. } => {

View File

@ -175,6 +175,8 @@ where
}
};
tracing::debug!("select returned redeem encsig from message");
tx_redeem_encsig
};

View File

@ -152,6 +152,8 @@ where
Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)),
};
tracing::debug!("select returned transfer proof from message");
transfer_proof
};