diff --git a/Cargo.lock b/Cargo.lock index 3cde7b4f..cfadf94a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1690,6 +1690,7 @@ dependencies = [ "libp2p-dns", "libp2p-mplex", "libp2p-noise", + "libp2p-relay", "libp2p-request-response", "libp2p-swarm", "libp2p-swarm-derive", @@ -1798,6 +1799,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "libp2p-relay" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff268be6a9d6f3c6cca3b81bbab597b15217f9ad8787c6c40fc548c1af7cd24" +dependencies = [ + "asynchronous-codec", + "bytes 1.0.1", + "futures", + "futures-timer", + "libp2p-core", + "libp2p-swarm", + "log 0.4.14", + "pin-project 1.0.5", + "prost", + "prost-build", + "rand 0.7.3", + "smallvec", + "unsigned-varint 0.7.0", + "void", + "wasm-timer", +] + [[package]] name = "libp2p-request-response" version = "0.10.0" diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 742249c0..12b09fbf 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -27,7 +27,7 @@ directories-next = "2" ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", features = ["libsecp_compat", "serde"] } futures = { version = "0.3", default-features = false } itertools = "0.10" -libp2p = { version = "0.36", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response"] } +libp2p = { version = "0.36", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "relay"] } libp2p-async-await = { git = "https://github.com/comit-network/rust-libp2p-async-await" } miniscript = { version = "5", features = ["serde"] } monero = { version = "0.11", features = ["serde_support"] } diff --git a/swap/src/bin/asb.rs b/swap/src/bin/asb.rs index 3140d946..b804069a 100644 --- a/swap/src/bin/asb.rs +++ b/swap/src/bin/asb.rs @@ -33,6 +33,8 @@ use swap::trace::init_tracing; use swap::{bitcoin, env, kraken, monero}; use tracing::{info, warn}; use tracing_subscriber::filter::LevelFilter; +use libp2p::core::Multiaddr; +use std::str::FromStr; #[macro_use] extern crate prettytable; @@ -99,7 +101,11 @@ async fn main() -> Result<()> { let kraken_price_updates = kraken::connect()?; let mut swarm = swarm::new::(&seed)?; - Swarm::listen_on(&mut swarm, config.network.listen) + + + let relay_addr = Multiaddr::from_str("/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN/p2p-circuit/dns4/xmr-btc-asb.coblox.tech/tcp/8765/p2p/12D3KooWPZ69DRp4wbGB3wJsxxsg1XW1EVZ2evtVwcARCF3a1nrx").expect("default relay multiaddress to be valid"); + + Swarm::listen_on(&mut swarm, relay_addr) .context("Failed to listen network interface")?; let (event_loop, mut swap_receiver) = EventLoop::new( diff --git a/swap/src/network.rs b/swap/src/network.rs index 4a3fb29e..11524444 100644 --- a/swap/src/network.rs +++ b/swap/src/network.rs @@ -4,4 +4,3 @@ pub mod quote; pub mod spot_price; pub mod swarm; pub mod transfer_proof; -pub mod transport; diff --git a/swap/src/network/swarm.rs b/swap/src/network/swarm.rs index 40e9f6d4..a1fe1a21 100644 --- a/swap/src/network/swarm.rs +++ b/swap/src/network/swarm.rs @@ -1,18 +1,40 @@ -use crate::network::transport; use crate::seed::Seed; use anyhow::Result; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; -use libp2p::Swarm; +use libp2p::{Swarm, Transport, yamux}; +use libp2p::relay::{RelayConfig, new_transport_and_behaviour, Relay}; +use libp2p::tcp::TokioTcpConfig; +use libp2p::dns::TokioDnsConfig; +use libp2p::core::upgrade::{Version, SelectUpgrade}; +use libp2p::mplex::MplexConfig; +use libp2p::core::muxing::StreamMuxerBox; +use libp2p::noise::{self, NoiseConfig, X25519Spec}; pub fn new(seed: &Seed) -> Result> where - B: NetworkBehaviour + Default, + B: NetworkBehaviour + From, { let identity = seed.derive_libp2p_identity(); - let behaviour = B::default(); - let transport = transport::build(&identity)?; + let dh_keys = noise::Keypair::::new().into_authentic(&identity)?; + let noise = NoiseConfig::xx(dh_keys).into_authenticated(); + let tcp = TokioTcpConfig::new().nodelay(true); + let dns = TokioDnsConfig::system(tcp)?; + + let (relay_transport, relay_behaviour) = new_transport_and_behaviour(RelayConfig::default(), dns); + + let transport = relay_transport + .upgrade(Version::V1) + .authenticate(noise) + .multiplex(SelectUpgrade::new( + yamux::YamuxConfig::default(), + MplexConfig::new(), + )) + .map(|(peer, muxer), _| (peer, StreamMuxerBox::new(muxer))) + .boxed(); + + let behaviour = B::from(relay_behaviour); let swarm = SwarmBuilder::new(transport, behaviour, identity.public().into_peer_id()) .executor(Box::new(|f| { tokio::spawn(f); diff --git a/swap/src/network/transport.rs b/swap/src/network/transport.rs deleted file mode 100644 index dc12cda3..00000000 --- a/swap/src/network/transport.rs +++ /dev/null @@ -1,38 +0,0 @@ -use anyhow::Result; -use libp2p::core::muxing::StreamMuxerBox; -use libp2p::core::transport::Boxed; -use libp2p::core::upgrade::{SelectUpgrade, Version}; -use libp2p::core::{identity, Transport}; -use libp2p::dns::TokioDnsConfig; -use libp2p::mplex::MplexConfig; -use libp2p::noise::{self, NoiseConfig, X25519Spec}; -use libp2p::{yamux, PeerId}; - -/// Builds a libp2p transport with the following features: -/// - TcpConnection -/// - DNS name resolution -/// - authentication via noise -/// - multiplexing via yamux or mplex -pub fn build(id_keys: &identity::Keypair) -> Result { - use libp2p::tcp::TokioTcpConfig; - - let dh_keys = noise::Keypair::::new().into_authentic(id_keys)?; - let noise = NoiseConfig::xx(dh_keys).into_authenticated(); - - let tcp = TokioTcpConfig::new().nodelay(true); - let dns = TokioDnsConfig::system(tcp)?; - - let transport = dns - .upgrade(Version::V1) - .authenticate(noise) - .multiplex(SelectUpgrade::new( - yamux::YamuxConfig::default(), - MplexConfig::new(), - )) - .map(|(peer, muxer), _| (peer, StreamMuxerBox::new(muxer))) - .boxed(); - - Ok(transport) -} - -pub type SwapTransport = Boxed<(PeerId, StreamMuxerBox)>; diff --git a/swap/src/protocol/alice/behaviour.rs b/swap/src/protocol/alice/behaviour.rs index 9ecaf49d..acf40d3c 100644 --- a/swap/src/protocol/alice/behaviour.rs +++ b/swap/src/protocol/alice/behaviour.rs @@ -6,6 +6,7 @@ use libp2p::request_response::{ RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; use libp2p::{NetworkBehaviour, PeerId}; +use libp2p::relay::Relay; #[derive(Debug)] pub enum OutEvent { @@ -54,6 +55,12 @@ impl OutEvent { } } +impl From<()> for OutEvent { + fn from(_: ()) -> Self { + unimplemented!() + } +} + impl From<(PeerId, quote::Message)> for OutEvent { fn from((peer, message): (PeerId, quote::Message)) -> Self { match message { @@ -177,16 +184,18 @@ pub struct Behaviour { pub execution_setup: execution_setup::Behaviour, pub transfer_proof: transfer_proof::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour, + pub relay: Relay, } -impl Default for Behaviour { - fn default() -> Self { +impl From for Behaviour { + fn from(relay: Relay) -> Self { Self { quote: quote::alice(), spot_price: spot_price::alice(), execution_setup: Default::default(), transfer_proof: transfer_proof::alice(), encrypted_signature: encrypted_signature::alice(), + relay, } } } diff --git a/swap/src/protocol/bob.rs b/swap/src/protocol/bob.rs index bb411560..cef8c8bc 100644 --- a/swap/src/protocol/bob.rs +++ b/swap/src/protocol/bob.rs @@ -19,6 +19,7 @@ pub use self::state::*; pub use self::swap::{run, run_until}; use crate::network::quote::BidQuote; use crate::network::{quote, transfer_proof}; +use libp2p::relay::Relay; pub mod cancel; pub mod event_loop; @@ -139,6 +140,12 @@ impl OutEvent { } } +impl From<()> for OutEvent { + fn from(_: ()) -> Self { + unimplemented!() + } +} + impl From for OutEvent { fn from(message: quote::Message) -> Self { match message { @@ -258,16 +265,18 @@ pub struct Behaviour { pub execution_setup: execution_setup::Behaviour, pub transfer_proof: transfer_proof::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour, + pub relay: Relay, } -impl Default for Behaviour { - fn default() -> Self { +impl From for Behaviour { + fn from(relay: Relay) -> Self { Self { quote: quote::bob(), spot_price: spot_price::bob(), execution_setup: Default::default(), transfer_proof: transfer_proof::bob(), encrypted_signature: encrypted_signature::bob(), + relay, } } }