use ecdsa_fun::{adaptor::EncryptedSignature, Signature}; use libp2p::{ request_response::{ handler::RequestProtocol, ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }, swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}, NetworkBehaviour, }; use serde::{Deserialize, Serialize}; use std::{ collections::VecDeque, task::{Context, Poll}, time::Duration, }; use tracing::{debug, error}; use crate::{ network::request_response::{AliceToBob, BobToAlice, Codec, Message1Protocol, TIMEOUT}, protocol::bob, }; #[derive(Debug)] pub enum OutEvent { Msg { /// Received message from Bob. msg: bob::Message1, /// Channel to send back Alice's message 1. channel: ResponseChannel, }, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Message1 { pub(crate) tx_cancel_sig: Signature, pub(crate) tx_refund_encsig: EncryptedSignature, } /// A `NetworkBehaviour` that represents send/recv of message 1. #[derive(NetworkBehaviour)] #[behaviour(out_event = "OutEvent", poll_method = "poll")] #[allow(missing_debug_implementations)] pub struct Behaviour { rr: RequestResponse>, #[behaviour(ignore)] events: VecDeque, } impl Behaviour { pub fn send(&mut self, channel: ResponseChannel, msg: Message1) { let msg = AliceToBob::Message1(Box::new(msg)); self.rr.send_response(channel, msg); } fn poll( &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, ) -> Poll>, 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( Codec::default(), vec![(Message1Protocol, ProtocolSupport::Full)], config, ), events: Default::default(), } } } impl NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: RequestResponseEvent) { match event { RequestResponseEvent::Message { message: RequestResponseMessage::Request { request, channel, .. }, .. } => { if let BobToAlice::Message1(msg) = request { debug!("Received Message1"); self.events.push_back(OutEvent::Msg { msg, channel }); } } RequestResponseEvent::Message { message: RequestResponseMessage::Response { .. }, .. } => panic!("Alice should not get a Response"), RequestResponseEvent::InboundFailure { error, .. } => { error!("Inbound failure: {:?}", error); } RequestResponseEvent::OutboundFailure { error, .. } => { error!("Outbound failure: {:?}", error); } } } }