Skip to content
This repository was archived by the owner on Mar 23, 2021. It is now read-only.

Commit 1e768bf

Browse files
Merge #1751
1751: Merge the `SendRequest` trait into the `Network` trait r=mergify[bot] a=thomaseizinger Fixes #1681. Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2 parents bbab527 + fbc0bfb commit 1e768bf

File tree

7 files changed

+150
-201
lines changed

7 files changed

+150
-201
lines changed

cnd/src/http_api/route_factory.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
config::settings::AllowedOrigins,
33
db::{DetermineTypes, Retrieve, Saver},
44
http_api,
5-
network::{Network, SendRequest},
5+
network::Network,
66
seed::SwapSeed,
77
swap_protocols::{self, rfc003::state_store::StateStore, LedgerEventsCreator, SwapId},
88
};
@@ -25,7 +25,6 @@ pub fn create<
2525
+ StateStore
2626
+ Executor
2727
+ Network
28-
+ SendRequest
2928
+ SwapSeed
3029
+ DetermineTypes
3130
+ Retrieve

cnd/src/http_api/routes/rfc003/handlers/post_swap.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
db::{Save, Saver, Swap},
33
ethereum,
44
http_api::{HttpAsset, HttpLedger},
5-
network::{DialInformation, SendRequest},
5+
network::{DialInformation, Network},
66
seed::SwapSeed,
77
swap_protocols::{
88
self,
@@ -32,9 +32,9 @@ pub async fn handle_post_swap<
3232
+ Executor
3333
+ StateStore
3434
+ Save<Swap>
35-
+ SendRequest
3635
+ SwapSeed
3736
+ Saver
37+
+ Network
3838
+ Clone
3939
+ LedgerEventsCreator,
4040
>(
@@ -210,12 +210,12 @@ async fn initiate_request<D, AL, BL, AA, BA>(
210210
where
211211
D: StateStore
212212
+ Executor
213-
+ SendRequest
214213
+ SwapSeed
215214
+ Save<Request<AL, BL, AA, BA>>
216215
+ Save<Accept<AL, BL>>
217216
+ Save<Swap>
218217
+ Save<Decline>
218+
+ Network
219219
+ LedgerEventsCreator
220220
+ CreateLedgerEvents<AL, AA>
221221
+ CreateLedgerEvents<BL, BA>

cnd/src/http_api/routes/rfc003/mod.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
rfc003::handlers::{handle_action, handle_get_swap, handle_post_swap},
1414
},
1515
},
16-
network::{Network, SendRequest},
16+
network::Network,
1717
seed::SwapSeed,
1818
swap_protocols::{
1919
rfc003::{actions::ActionKind, state_store::StateStore},
@@ -31,14 +31,7 @@ use tokio::executor::Executor;
3131

3232
#[allow(clippy::needless_pass_by_value)]
3333
pub fn post_swap<
34-
D: Clone
35-
+ StateStore
36-
+ Executor
37-
+ Save<Swap>
38-
+ SendRequest
39-
+ SwapSeed
40-
+ Saver
41-
+ LedgerEventsCreator,
34+
D: Clone + Network + StateStore + Executor + Save<Swap> + SwapSeed + Saver + LedgerEventsCreator,
4235
>(
4336
dependencies: D,
4437
body: serde_json::Value,

cnd/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use cnd::{
88
db::{DetermineTypes, Retrieve, Saver, Sqlite},
99
http_api::route_factory,
1010
load_swaps,
11-
network::{self, transport, Network, SendRequest},
11+
network::{self, transport, Network},
1212
seed::{Seed, SwapSeed},
1313
swap_protocols::{
1414
rfc003::state_store::{InMemoryStateStore, StateStore},
@@ -126,7 +126,6 @@ fn spawn_warp_instance<
126126
+ StateStore
127127
+ Executor
128128
+ Network
129-
+ SendRequest
130129
+ SwapSeed
131130
+ DetermineTypes
132131
+ Retrieve

cnd/src/network/mod.rs

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
pub mod send_request;
21
pub mod transport;
32

4-
pub use send_request::*;
5-
63
use crate::{
74
btsieve::{bitcoin::BitcoindConnector, ethereum::Web3Connector},
85
db::{Save, Saver, Sqlite, Swap},
@@ -31,7 +28,7 @@ use libp2p::{
3128
Multiaddr, NetworkBehaviour, PeerId, Swarm, Transport,
3229
};
3330
use libp2p_comit::{
34-
frame::{OutboundRequest, Response, ValidatedInboundRequest},
31+
frame::{self, OutboundRequest, Response, ValidatedInboundRequest},
3532
BehaviourOutEvent, Comit, PendingInboundRequest,
3633
};
3734
use std::{
@@ -79,6 +76,23 @@ impl Display for DialInformation {
7976
}
8077
}
8178

79+
#[derive(Debug, thiserror::Error)]
80+
pub enum RequestError {
81+
#[error("peer node had an internal error while processing the request")]
82+
InternalError,
83+
#[error("peer node produced an invalid response")]
84+
InvalidResponse,
85+
#[error("failed to establish a new connection to make the request")]
86+
Connecting(io::ErrorKind),
87+
#[error("unable to send the data on the existing connection")]
88+
Connection,
89+
}
90+
91+
#[derive(Debug, serde::Deserialize)]
92+
pub struct Reason {
93+
pub value: SwapDeclineReason,
94+
}
95+
8296
impl<TSubstream> ComitNode<TSubstream> {
8397
pub fn new(
8498
bitcoin_connector: BitcoindConnector,
@@ -340,10 +354,22 @@ where
340354
Ok(())
341355
}
342356

357+
/// Defines all the operations the Comit Node can perform in regards to the
358+
/// Comit network.
359+
///
360+
/// Ideally, this trait would not be necessary and we would instead have one
361+
/// trait per function. Unfortunately, an instance of `Swarm` is very hard to
362+
/// name (see the complex traits bound below). To avoid this kind of code 4
363+
/// times, we bundle all these methods up into one trait.
343364
pub trait Network: Send + Sync + 'static {
344365
fn comit_peers(&self) -> Box<dyn Iterator<Item = (PeerId, Vec<Multiaddr>)> + Send + 'static>;
345366
fn listen_addresses(&self) -> Vec<Multiaddr>;
346367
fn pending_request_for(&self, swap: SwapId) -> Option<oneshot::Sender<Response>>;
368+
fn send_request<AL: rfc003::Ledger, BL: rfc003::Ledger, AA: Asset, BA: Asset>(
369+
&self,
370+
peer_identity: DialInformation,
371+
request: rfc003::Request<AL, BL, AA, BA>,
372+
) -> Box<dyn Future<Item = rfc003::Response<AL, BL>, Error = RequestError> + Send>;
347373
}
348374

349375
impl<
@@ -380,6 +406,85 @@ where
380406

381407
response_channels.remove(&swap)
382408
}
409+
410+
fn send_request<AL: rfc003::Ledger, BL: rfc003::Ledger, AA: Asset, BA: Asset>(
411+
&self,
412+
dial_information: DialInformation,
413+
request: rfc003::Request<AL, BL, AA, BA>,
414+
) -> Box<dyn Future<Item = rfc003::Response<AL, BL>, Error = RequestError> + Send> {
415+
let id = request.swap_id;
416+
let request = build_outbound_request(request)
417+
.expect("constructing a frame::OutoingRequest should never fail!");
418+
419+
let response = {
420+
let mut swarm = self.lock().unwrap();
421+
log::debug!(
422+
"Making swap request to {}: {:?}",
423+
dial_information.clone(),
424+
request
425+
);
426+
427+
swarm.send_request(dial_information.clone(), request)
428+
};
429+
430+
let response =
431+
response.then(move |result| match result {
432+
Ok(mut response) => {
433+
let decision = response
434+
.take_header("decision")
435+
.map(Decision::from_header)
436+
.map_or(Ok(None), |x| x.map(Some))
437+
.map_err(|e| {
438+
log::error!(
439+
"Could not deserialize header in response {:?}: {}",
440+
response,
441+
e,
442+
);
443+
RequestError::InvalidResponse
444+
})?;
445+
446+
match decision {
447+
Some(Decision::Accepted) => {
448+
match serde_json::from_value::<
449+
rfc003::messages::AcceptResponseBody<AL, BL>,
450+
>(response.body().clone())
451+
{
452+
Ok(body) => Ok(Ok(rfc003::Accept {
453+
swap_id: id,
454+
beta_ledger_refund_identity: body.beta_ledger_refund_identity,
455+
alpha_ledger_redeem_identity: body.alpha_ledger_redeem_identity,
456+
})),
457+
Err(_e) => Err(RequestError::InvalidResponse),
458+
}
459+
}
460+
461+
Some(Decision::Declined) => {
462+
match serde_json::from_value::<rfc003::messages::DeclineResponseBody>(
463+
response.body().clone(),
464+
) {
465+
Ok(body) => Ok(Err(rfc003::Decline {
466+
swap_id: id,
467+
reason: body.reason,
468+
})),
469+
Err(_e) => Err(RequestError::InvalidResponse),
470+
}
471+
}
472+
473+
None => Err(RequestError::InvalidResponse),
474+
}
475+
}
476+
Err(e) => {
477+
log::error!(
478+
"Unable to request over connection {:?}:{:?}",
479+
dial_information.clone(),
480+
e
481+
);
482+
Err(RequestError::Connection)
483+
}
484+
});
485+
486+
Box::new(response)
487+
}
383488
}
384489

385490
impl<TSubstream> NetworkBehaviourEventProcess<BehaviourOutEvent> for ComitNode<TSubstream> {
@@ -460,3 +565,32 @@ fn rfc003_swap_request<AL: rfc003::Ledger, BL: rfc003::Ledger, AA: Asset, BA: As
460565
secret_hash: body.secret_hash,
461566
}
462567
}
568+
569+
fn build_outbound_request<AL: rfc003::Ledger, BL: rfc003::Ledger, AA: Asset, BA: Asset>(
570+
request: rfc003::Request<AL, BL, AA, BA>,
571+
) -> Result<frame::OutboundRequest, serde_json::Error> {
572+
let alpha_ledger_refund_identity = request.alpha_ledger_refund_identity;
573+
let beta_ledger_redeem_identity = request.beta_ledger_redeem_identity;
574+
let alpha_expiry = request.alpha_expiry;
575+
let beta_expiry = request.beta_expiry;
576+
let secret_hash = request.secret_hash;
577+
let protocol = SwapProtocol::Rfc003(request.hash_function);
578+
579+
Ok(frame::OutboundRequest::new("SWAP")
580+
.with_header("id", request.swap_id.to_header()?)
581+
.with_header("alpha_ledger", request.alpha_ledger.into().to_header()?)
582+
.with_header("beta_ledger", request.beta_ledger.into().to_header()?)
583+
.with_header("alpha_asset", request.alpha_asset.into().to_header()?)
584+
.with_header("beta_asset", request.beta_asset.into().to_header()?)
585+
.with_header("protocol", protocol.to_header()?)
586+
.with_body(serde_json::to_value(rfc003::messages::RequestBody::<
587+
AL,
588+
BL,
589+
> {
590+
alpha_ledger_refund_identity,
591+
beta_ledger_redeem_identity,
592+
alpha_expiry,
593+
beta_expiry,
594+
secret_hash,
595+
})?))
596+
}

0 commit comments

Comments
 (0)