mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-28 00:49:39 -05:00
Use bmrng to model communicaton of Bob's EventLoop with the handle
bmrng is a library providing a request-response channel that allows the receiving end of the channel to send a response back to the sender. This allows us to more accurately implement the functions on the `EventLoopHandle`. In particular, we now _wait_ for the ACK of specific messages from the other party before resolving the future. For example, when sending the encrypted signature, the async function on the `EventLoopHandle` does not resolve until we received the ACK from the other party. We also delete the `Channels` abstraction in favor of directly creating bmrng channels. This allows us to directly control the channel buffer which we set to 1 because we don't need more than that on Bob's side.
This commit is contained in:
parent
958e5b12bc
commit
1c47b32681
51
Cargo.lock
generated
51
Cargo.lock
generated
@ -481,6 +481,17 @@ dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bmrng"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ba7ad917af2fc43efa0b20d2bf3b2c1bd1090fa2a6b8c73847458c8335dea2b"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"loom",
|
||||
"tokio 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.4.0"
|
||||
@ -1181,6 +1192,19 @@ dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "061d3be1afec479d56fa3bd182bf966c7999ec175fcfdb87ac14d417241366c6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"log 0.4.14",
|
||||
"rustversion",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
@ -1909,6 +1933,20 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d44c73b4636e497b4917eb21c33539efa3816741a2d3ff26c6316f1b529481a4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"futures-util",
|
||||
"generator",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.6.5"
|
||||
@ -3014,6 +3052,12 @@ dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
|
||||
|
||||
[[package]]
|
||||
name = "rw-stream-sink"
|
||||
version = "0.2.1"
|
||||
@ -3037,6 +3081,12 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -3522,6 +3572,7 @@ dependencies = [
|
||||
"big-bytes",
|
||||
"bitcoin",
|
||||
"bitcoin-harness",
|
||||
"bmrng",
|
||||
"config",
|
||||
"conquer-once",
|
||||
"curve25519-dalek",
|
||||
|
@ -18,6 +18,7 @@ base64 = "0.13"
|
||||
bdk = { version = "0.5" }
|
||||
big-bytes = "1"
|
||||
bitcoin = { version = "0.26", features = ["rand", "use-serde"] }
|
||||
bmrng = "0.5"
|
||||
config = { version = "0.11", default-features = false, features = ["toml"] }
|
||||
conquer-once = "0.3"
|
||||
curve25519-dalek = "3"
|
||||
|
@ -5,7 +5,9 @@ use crate::protocol::bob;
|
||||
use crate::{bitcoin, monero};
|
||||
use anyhow::{anyhow, Error, Result};
|
||||
use libp2p::core::Multiaddr;
|
||||
use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel};
|
||||
use libp2p::request_response::{
|
||||
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
|
||||
};
|
||||
use libp2p::{NetworkBehaviour, PeerId};
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
@ -107,14 +109,22 @@ impl Builder {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OutEvent {
|
||||
QuoteReceived(BidQuote),
|
||||
SpotPriceReceived(spot_price::Response),
|
||||
ExecutionSetupDone(Result<Box<State2>>),
|
||||
QuoteReceived {
|
||||
id: RequestId,
|
||||
response: BidQuote,
|
||||
},
|
||||
SpotPriceReceived {
|
||||
id: RequestId,
|
||||
response: spot_price::Response,
|
||||
},
|
||||
ExecutionSetupDone(Box<Result<State2>>),
|
||||
TransferProofReceived {
|
||||
msg: Box<transfer_proof::Request>,
|
||||
channel: ResponseChannel<()>,
|
||||
},
|
||||
EncryptedSignatureAcknowledged,
|
||||
EncryptedSignatureAcknowledged {
|
||||
id: RequestId,
|
||||
},
|
||||
ResponseSent, // Same variant is used for all messages as no processing is done
|
||||
CommunicationError(Error),
|
||||
}
|
||||
@ -133,7 +143,13 @@ impl From<quote::Message> for OutEvent {
|
||||
fn from(message: quote::Message) -> Self {
|
||||
match message {
|
||||
quote::Message::Request { .. } => OutEvent::unexpected_request(),
|
||||
quote::Message::Response { response, .. } => OutEvent::QuoteReceived(response),
|
||||
quote::Message::Response {
|
||||
response,
|
||||
request_id,
|
||||
} => OutEvent::QuoteReceived {
|
||||
id: request_id,
|
||||
response,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,7 +158,13 @@ impl From<spot_price::Message> for OutEvent {
|
||||
fn from(message: spot_price::Message) -> Self {
|
||||
match message {
|
||||
spot_price::Message::Request { .. } => OutEvent::unexpected_request(),
|
||||
spot_price::Message::Response { response, .. } => OutEvent::SpotPriceReceived(response),
|
||||
spot_price::Message::Response {
|
||||
response,
|
||||
request_id,
|
||||
} => OutEvent::SpotPriceReceived {
|
||||
id: request_id,
|
||||
response,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,8 +187,8 @@ impl From<encrypted_signature::Message> for OutEvent {
|
||||
fn from(message: encrypted_signature::Message) -> Self {
|
||||
match message {
|
||||
encrypted_signature::Message::Request { .. } => OutEvent::unexpected_request(),
|
||||
encrypted_signature::Message::Response { .. } => {
|
||||
OutEvent::EncryptedSignatureAcknowledged
|
||||
encrypted_signature::Message::Response { request_id, .. } => {
|
||||
OutEvent::EncryptedSignatureAcknowledged { id: request_id }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -221,7 +243,7 @@ where
|
||||
impl From<execution_setup::OutEvent> for OutEvent {
|
||||
fn from(event: execution_setup::OutEvent) -> Self {
|
||||
match event {
|
||||
execution_setup::OutEvent::Done(res) => OutEvent::ExecutionSetupDone(res.map(Box::new)),
|
||||
execution_setup::OutEvent::Done(res) => OutEvent::ExecutionSetupDone(Box::new(res)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,27 +3,46 @@ use crate::network::quote::BidQuote;
|
||||
use crate::network::{encrypted_signature, spot_price, transfer_proof};
|
||||
use crate::protocol::bob::{Behaviour, OutEvent, State0, State2};
|
||||
use crate::{bitcoin, monero};
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::FutureExt;
|
||||
use anyhow::{Context, Result};
|
||||
use futures::future::{BoxFuture, OptionFuture};
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use libp2p::request_response::{RequestId, ResponseChannel};
|
||||
use libp2p::swarm::SwarmEvent;
|
||||
use libp2p::{PeerId, Swarm};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc::{Receiver, Sender};
|
||||
use tracing::{debug, error};
|
||||
use std::time::Duration;
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct EventLoop {
|
||||
swarm: libp2p::Swarm<Behaviour>,
|
||||
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
||||
alice_peer_id: PeerId,
|
||||
request_spot_price: Receiver<spot_price::Request>,
|
||||
recv_spot_price: Sender<spot_price::Response>,
|
||||
start_execution_setup: Receiver<State0>,
|
||||
done_execution_setup: Sender<Result<State2>>,
|
||||
recv_transfer_proof: Sender<transfer_proof::Request>,
|
||||
send_encrypted_signature: Receiver<encrypted_signature::Request>,
|
||||
request_quote: Receiver<()>,
|
||||
recv_quote: Sender<BidQuote>,
|
||||
|
||||
// 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, ()>,
|
||||
execution_setup_requests: bmrng::RequestReceiverStream<State0, Result<State2>>,
|
||||
|
||||
// these represents requests that are currently in-flight.
|
||||
// once we get a response to a matching [`RequestId`], we will use the responder to relay the
|
||||
// response.
|
||||
inflight_spot_price_requests: HashMap<RequestId, bmrng::Responder<spot_price::Response>>,
|
||||
inflight_quote_requests: HashMap<RequestId, bmrng::Responder<BidQuote>>,
|
||||
inflight_encrypted_signature_requests: HashMap<RequestId, bmrng::Responder<()>>,
|
||||
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, ()>,
|
||||
/// The future representing the successful handling of an incoming transfer
|
||||
/// proof.
|
||||
///
|
||||
/// Once we've sent a transfer proof to the ongoing swap, this future waits
|
||||
/// until the swap took it "out" of the `EventLoopHandle`. As this future
|
||||
/// resolves, we use the `ResponseChannel` returned from it to send an ACK
|
||||
/// to Alice that we have successfully processed the transfer proof.
|
||||
pending_transfer_proof: OptionFuture<BoxFuture<'static, ResponseChannel<()>>>,
|
||||
}
|
||||
|
||||
impl EventLoop {
|
||||
@ -32,38 +51,34 @@ impl EventLoop {
|
||||
alice_peer_id: PeerId,
|
||||
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
||||
) -> Result<(Self, EventLoopHandle)> {
|
||||
let start_execution_setup = Channels::new();
|
||||
let done_execution_setup = Channels::new();
|
||||
let recv_transfer_proof = Channels::new();
|
||||
let send_encrypted_signature = Channels::new();
|
||||
let request_spot_price = Channels::new();
|
||||
let recv_spot_price = Channels::new();
|
||||
let request_quote = Channels::new();
|
||||
let recv_quote = Channels::new();
|
||||
let execution_setup = bmrng::channel_with_timeout(1, Duration::from_secs(30));
|
||||
let transfer_proof = bmrng::channel_with_timeout(1, Duration::from_secs(30));
|
||||
let encrypted_signature = bmrng::channel_with_timeout(1, Duration::from_secs(30));
|
||||
let spot_price = bmrng::channel_with_timeout(1, Duration::from_secs(30));
|
||||
let quote = bmrng::channel_with_timeout(1, Duration::from_secs(30));
|
||||
|
||||
let event_loop = EventLoop {
|
||||
swarm,
|
||||
alice_peer_id,
|
||||
bitcoin_wallet,
|
||||
start_execution_setup: start_execution_setup.receiver,
|
||||
done_execution_setup: done_execution_setup.sender,
|
||||
recv_transfer_proof: recv_transfer_proof.sender,
|
||||
send_encrypted_signature: send_encrypted_signature.receiver,
|
||||
request_spot_price: request_spot_price.receiver,
|
||||
recv_spot_price: recv_spot_price.sender,
|
||||
request_quote: request_quote.receiver,
|
||||
recv_quote: recv_quote.sender,
|
||||
execution_setup_requests: execution_setup.1.into(),
|
||||
transfer_proof: transfer_proof.0,
|
||||
encrypted_signature_requests: encrypted_signature.1.into(),
|
||||
spot_price_requests: spot_price.1.into(),
|
||||
quote_requests: quote.1.into(),
|
||||
inflight_spot_price_requests: HashMap::default(),
|
||||
inflight_quote_requests: HashMap::default(),
|
||||
inflight_execution_setup: None,
|
||||
inflight_encrypted_signature_requests: HashMap::default(),
|
||||
pending_transfer_proof: OptionFuture::from(None),
|
||||
};
|
||||
|
||||
let handle = EventLoopHandle {
|
||||
start_execution_setup: start_execution_setup.sender,
|
||||
done_execution_setup: done_execution_setup.receiver,
|
||||
recv_transfer_proof: recv_transfer_proof.receiver,
|
||||
send_encrypted_signature: send_encrypted_signature.sender,
|
||||
request_spot_price: request_spot_price.sender,
|
||||
recv_spot_price: recv_spot_price.receiver,
|
||||
request_quote: request_quote.sender,
|
||||
recv_quote: recv_quote.receiver,
|
||||
execution_setup: execution_setup.0,
|
||||
transfer_proof: transfer_proof.1,
|
||||
encrypted_signature: encrypted_signature.0,
|
||||
spot_price: spot_price.0,
|
||||
quote: quote.0,
|
||||
};
|
||||
|
||||
Ok((event_loop, handle))
|
||||
@ -76,24 +91,40 @@ impl EventLoop {
|
||||
tokio::select! {
|
||||
swarm_event = self.swarm.next_event().fuse() => {
|
||||
match swarm_event {
|
||||
SwarmEvent::Behaviour(OutEvent::SpotPriceReceived(msg)) => {
|
||||
let _ = self.recv_spot_price.send(msg).await;
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::QuoteReceived(msg)) => {
|
||||
let _ = self.recv_quote.send(msg).await;
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::ExecutionSetupDone(res)) => {
|
||||
let _ = self.done_execution_setup.send(res.map(|state|*state)).await;
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::TransferProofReceived{ msg, channel }) => {
|
||||
let _ = self.recv_transfer_proof.send(*msg).await;
|
||||
// Send back empty response so that the request/response protocol completes.
|
||||
if let Err(error) = self.swarm.transfer_proof.send_response(channel, ()) {
|
||||
error!("Failed to send Transfer Proof ack: {:?}", error);
|
||||
SwarmEvent::Behaviour(OutEvent::SpotPriceReceived { id, response }) => {
|
||||
if let Some(responder) = self.inflight_spot_price_requests.remove(&id) {
|
||||
let _ = responder.respond(response);
|
||||
}
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::EncryptedSignatureAcknowledged) => {
|
||||
debug!("Alice acknowledged encrypted signature");
|
||||
SwarmEvent::Behaviour(OutEvent::QuoteReceived { id, response }) => {
|
||||
if let Some(responder) = self.inflight_quote_requests.remove(&id) {
|
||||
let _ = responder.respond(response);
|
||||
}
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::ExecutionSetupDone(response)) => {
|
||||
if let Some(responder) = self.inflight_execution_setup.take() {
|
||||
let _ = responder.respond(*response);
|
||||
}
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::TransferProofReceived { msg, channel }) => {
|
||||
let mut responder = match self.transfer_proof.send(*msg).await {
|
||||
Ok(responder) => responder,
|
||||
Err(_) => {
|
||||
tracing::warn!("Failed to pass on transfer proof");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
self.pending_transfer_proof = OptionFuture::from(Some(async move {
|
||||
let _ = responder.recv().await;
|
||||
|
||||
channel
|
||||
}.boxed()));
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::EncryptedSignatureAcknowledged { id }) => {
|
||||
if let Some(responder) = self.inflight_encrypted_signature_requests.remove(&id) {
|
||||
let _ = responder.respond(());
|
||||
}
|
||||
}
|
||||
SwarmEvent::Behaviour(OutEvent::ResponseSent) => {
|
||||
|
||||
@ -133,27 +164,26 @@ impl EventLoop {
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
spot_price_request = self.request_spot_price.recv().fuse() => {
|
||||
if let Some(request) = spot_price_request {
|
||||
self.swarm.spot_price.send_request(&self.alice_peer_id, request);
|
||||
}
|
||||
Some((request, responder)) = self.spot_price_requests.next().fuse() => {
|
||||
let id = self.swarm.spot_price.send_request(&self.alice_peer_id, request);
|
||||
self.inflight_spot_price_requests.insert(id, responder);
|
||||
},
|
||||
quote_request = self.request_quote.recv().fuse() => {
|
||||
if quote_request.is_some() {
|
||||
self.swarm.quote.send_request(&self.alice_peer_id, ());
|
||||
}
|
||||
Some(((), responder)) = self.quote_requests.next().fuse() => {
|
||||
let id = self.swarm.quote.send_request(&self.alice_peer_id, ());
|
||||
self.inflight_quote_requests.insert(id, responder);
|
||||
},
|
||||
option = self.start_execution_setup.recv().fuse() => {
|
||||
if let Some(state0) = option {
|
||||
let _ = self
|
||||
.swarm
|
||||
.execution_setup.run(self.alice_peer_id, state0, self.bitcoin_wallet.clone());
|
||||
}
|
||||
Some((request, responder)) = self.execution_setup_requests.next().fuse() => {
|
||||
self.swarm.execution_setup.run(self.alice_peer_id, request, self.bitcoin_wallet.clone());
|
||||
self.inflight_execution_setup = Some(responder);
|
||||
},
|
||||
encrypted_signature = self.send_encrypted_signature.recv().fuse() => {
|
||||
if let Some(tx_redeem_encsig) = encrypted_signature {
|
||||
self.swarm.encrypted_signature.send_request(&self.alice_peer_id, tx_redeem_encsig);
|
||||
}
|
||||
Some((request, responder)) = self.encrypted_signature_requests.next().fuse() => {
|
||||
let id = self.swarm.encrypted_signature.send_request(&self.alice_peer_id, request);
|
||||
self.inflight_encrypted_signature_requests.insert(id, responder);
|
||||
},
|
||||
Some(response_channel) = &mut self.pending_transfer_proof => {
|
||||
let _ = self.swarm.transfer_proof.send_response(response_channel, ());
|
||||
|
||||
self.pending_transfer_proof = OptionFuture::from(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,87 +192,50 @@ impl EventLoop {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventLoopHandle {
|
||||
start_execution_setup: Sender<State0>,
|
||||
done_execution_setup: Receiver<Result<State2>>,
|
||||
recv_transfer_proof: Receiver<transfer_proof::Request>,
|
||||
send_encrypted_signature: Sender<encrypted_signature::Request>,
|
||||
request_spot_price: Sender<spot_price::Request>,
|
||||
recv_spot_price: Receiver<spot_price::Response>,
|
||||
request_quote: Sender<()>,
|
||||
recv_quote: Receiver<BidQuote>,
|
||||
execution_setup: bmrng::RequestSender<State0, Result<State2>>,
|
||||
transfer_proof: bmrng::RequestReceiver<transfer_proof::Request, ()>,
|
||||
encrypted_signature: bmrng::RequestSender<encrypted_signature::Request, ()>,
|
||||
spot_price: bmrng::RequestSender<spot_price::Request, spot_price::Response>,
|
||||
quote: bmrng::RequestSender<(), BidQuote>,
|
||||
}
|
||||
|
||||
impl EventLoopHandle {
|
||||
pub async fn execution_setup(&mut self, state0: State0) -> Result<State2> {
|
||||
let _ = self.start_execution_setup.send(state0).await?;
|
||||
|
||||
self.done_execution_setup
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to setup execution with Alice"))?
|
||||
self.execution_setup.send_receive(state0).await?
|
||||
}
|
||||
|
||||
pub async fn recv_transfer_proof(&mut self) -> Result<transfer_proof::Request> {
|
||||
self.recv_transfer_proof
|
||||
let (request, responder) = self
|
||||
.transfer_proof
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive transfer proof from Alice"))
|
||||
.context("Failed to receive transfer proof")?;
|
||||
responder
|
||||
.respond(())
|
||||
.context("Failed to acknowledge receipt of transfer proof")?;
|
||||
|
||||
Ok(request)
|
||||
}
|
||||
|
||||
pub async fn request_spot_price(&mut self, btc: bitcoin::Amount) -> Result<monero::Amount> {
|
||||
let _ = self
|
||||
.request_spot_price
|
||||
.send(spot_price::Request { btc })
|
||||
.await?;
|
||||
|
||||
let response = self
|
||||
.recv_spot_price
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive spot price from Alice"))?;
|
||||
|
||||
Ok(response.xmr)
|
||||
Ok(self
|
||||
.spot_price
|
||||
.send_receive(spot_price::Request { btc })
|
||||
.await?
|
||||
.xmr)
|
||||
}
|
||||
|
||||
pub async fn request_quote(&mut self) -> Result<BidQuote> {
|
||||
let _ = self.request_quote.send(()).await?;
|
||||
|
||||
let quote = self
|
||||
.recv_quote
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive quote from Alice"))?;
|
||||
|
||||
Ok(quote)
|
||||
Ok(self.quote.send_receive(()).await?)
|
||||
}
|
||||
|
||||
pub async fn send_encrypted_signature(
|
||||
&mut self,
|
||||
tx_redeem_encsig: EncryptedSignature,
|
||||
) -> Result<()> {
|
||||
self.send_encrypted_signature
|
||||
.send(encrypted_signature::Request { tx_redeem_encsig })
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Channels<T> {
|
||||
sender: Sender<T>,
|
||||
receiver: Receiver<T>,
|
||||
}
|
||||
|
||||
impl<T> Channels<T> {
|
||||
fn new() -> Channels<T> {
|
||||
let (sender, receiver) = tokio::sync::mpsc::channel(100);
|
||||
Channels { sender, receiver }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for Channels<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
Ok(self
|
||||
.encrypted_signature
|
||||
.send_receive(encrypted_signature::Request { tx_redeem_encsig })
|
||||
.await?)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user