WIP relay

This commit is contained in:
Daniel Karzel 2021-04-07 15:23:04 +10:00
parent bad6ca95e0
commit 4c93725755
No known key found for this signature in database
GPG key ID: 30C3FC2E438ADB6E
8 changed files with 81 additions and 50 deletions

24
Cargo.lock generated
View file

@ -1690,6 +1690,7 @@ dependencies = [
"libp2p-dns", "libp2p-dns",
"libp2p-mplex", "libp2p-mplex",
"libp2p-noise", "libp2p-noise",
"libp2p-relay",
"libp2p-request-response", "libp2p-request-response",
"libp2p-swarm", "libp2p-swarm",
"libp2p-swarm-derive", "libp2p-swarm-derive",
@ -1798,6 +1799,29 @@ dependencies = [
"zeroize", "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]] [[package]]
name = "libp2p-request-response" name = "libp2p-request-response"
version = "0.10.0" version = "0.10.0"

View file

@ -27,7 +27,7 @@ directories-next = "2"
ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", features = ["libsecp_compat", "serde"] } ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", features = ["libsecp_compat", "serde"] }
futures = { version = "0.3", default-features = false } futures = { version = "0.3", default-features = false }
itertools = "0.10" 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" } libp2p-async-await = { git = "https://github.com/comit-network/rust-libp2p-async-await" }
miniscript = { version = "5", features = ["serde"] } miniscript = { version = "5", features = ["serde"] }
monero = { version = "0.11", features = ["serde_support"] } monero = { version = "0.11", features = ["serde_support"] }

View file

@ -33,6 +33,8 @@ use swap::trace::init_tracing;
use swap::{bitcoin, env, kraken, monero}; use swap::{bitcoin, env, kraken, monero};
use tracing::{info, warn}; use tracing::{info, warn};
use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::filter::LevelFilter;
use libp2p::core::Multiaddr;
use std::str::FromStr;
#[macro_use] #[macro_use]
extern crate prettytable; extern crate prettytable;
@ -99,7 +101,11 @@ async fn main() -> Result<()> {
let kraken_price_updates = kraken::connect()?; let kraken_price_updates = kraken::connect()?;
let mut swarm = swarm::new::<Behaviour>(&seed)?; let mut swarm = swarm::new::<Behaviour>(&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")?; .context("Failed to listen network interface")?;
let (event_loop, mut swap_receiver) = EventLoop::new( let (event_loop, mut swap_receiver) = EventLoop::new(

View file

@ -4,4 +4,3 @@ pub mod quote;
pub mod spot_price; pub mod spot_price;
pub mod swarm; pub mod swarm;
pub mod transfer_proof; pub mod transfer_proof;
pub mod transport;

View file

@ -1,18 +1,40 @@
use crate::network::transport;
use crate::seed::Seed; use crate::seed::Seed;
use anyhow::Result; use anyhow::Result;
use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; 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<B>(seed: &Seed) -> Result<Swarm<B>> pub fn new<B>(seed: &Seed) -> Result<Swarm<B>>
where where
B: NetworkBehaviour + Default, B: NetworkBehaviour + From<Relay>,
{ {
let identity = seed.derive_libp2p_identity(); let identity = seed.derive_libp2p_identity();
let behaviour = B::default(); let dh_keys = noise::Keypair::<X25519Spec>::new().into_authentic(&identity)?;
let transport = transport::build(&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()) let swarm = SwarmBuilder::new(transport, behaviour, identity.public().into_peer_id())
.executor(Box::new(|f| { .executor(Box::new(|f| {
tokio::spawn(f); tokio::spawn(f);

View file

@ -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<SwapTransport> {
use libp2p::tcp::TokioTcpConfig;
let dh_keys = noise::Keypair::<X25519Spec>::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)>;

View file

@ -6,6 +6,7 @@ use libp2p::request_response::{
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel, RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
}; };
use libp2p::{NetworkBehaviour, PeerId}; use libp2p::{NetworkBehaviour, PeerId};
use libp2p::relay::Relay;
#[derive(Debug)] #[derive(Debug)]
pub enum OutEvent { pub enum OutEvent {
@ -54,6 +55,12 @@ impl OutEvent {
} }
} }
impl From<()> for OutEvent {
fn from(_: ()) -> Self {
unimplemented!()
}
}
impl From<(PeerId, quote::Message)> for OutEvent { impl From<(PeerId, quote::Message)> for OutEvent {
fn from((peer, message): (PeerId, quote::Message)) -> Self { fn from((peer, message): (PeerId, quote::Message)) -> Self {
match message { match message {
@ -177,16 +184,18 @@ pub struct Behaviour {
pub execution_setup: execution_setup::Behaviour, pub execution_setup: execution_setup::Behaviour,
pub transfer_proof: transfer_proof::Behaviour, pub transfer_proof: transfer_proof::Behaviour,
pub encrypted_signature: encrypted_signature::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour,
pub relay: Relay,
} }
impl Default for Behaviour { impl From<Relay> for Behaviour {
fn default() -> Self { fn from(relay: Relay) -> Self {
Self { Self {
quote: quote::alice(), quote: quote::alice(),
spot_price: spot_price::alice(), spot_price: spot_price::alice(),
execution_setup: Default::default(), execution_setup: Default::default(),
transfer_proof: transfer_proof::alice(), transfer_proof: transfer_proof::alice(),
encrypted_signature: encrypted_signature::alice(), encrypted_signature: encrypted_signature::alice(),
relay,
} }
} }
} }

View file

@ -19,6 +19,7 @@ pub use self::state::*;
pub use self::swap::{run, run_until}; pub use self::swap::{run, run_until};
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::{quote, transfer_proof}; use crate::network::{quote, transfer_proof};
use libp2p::relay::Relay;
pub mod cancel; pub mod cancel;
pub mod event_loop; pub mod event_loop;
@ -139,6 +140,12 @@ impl OutEvent {
} }
} }
impl From<()> for OutEvent {
fn from(_: ()) -> Self {
unimplemented!()
}
}
impl From<quote::Message> for OutEvent { impl From<quote::Message> for OutEvent {
fn from(message: quote::Message) -> Self { fn from(message: quote::Message) -> Self {
match message { match message {
@ -258,16 +265,18 @@ pub struct Behaviour {
pub execution_setup: execution_setup::Behaviour, pub execution_setup: execution_setup::Behaviour,
pub transfer_proof: transfer_proof::Behaviour, pub transfer_proof: transfer_proof::Behaviour,
pub encrypted_signature: encrypted_signature::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour,
pub relay: Relay,
} }
impl Default for Behaviour { impl From<Relay> for Behaviour {
fn default() -> Self { fn from(relay: Relay) -> Self {
Self { Self {
quote: quote::bob(), quote: quote::bob(),
spot_price: spot_price::bob(), spot_price: spot_price::bob(),
execution_setup: Default::default(), execution_setup: Default::default(),
transfer_proof: transfer_proof::bob(), transfer_proof: transfer_proof::bob(),
encrypted_signature: encrypted_signature::bob(), encrypted_signature: encrypted_signature::bob(),
relay,
} }
} }
} }