diff --git a/Cargo.lock b/Cargo.lock index 0b007335..996a464a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2075,9 +2075,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" +checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" dependencies = [ "cc", "libc", @@ -2212,18 +2212,18 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "minicbor" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea79ce4ab9f445ec6b71833a2290ac0a29c9dde0fa7cae4c481eecae021d9bd9" +checksum = "51aa5bb0ca22415daca596a227b507f880ad1b2318a87fa9325312a5d285ca0d" dependencies = [ "minicbor-derive", ] [[package]] name = "minicbor-derive" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce18b5423c573a13e80cb3046ea0af6379ef725dc3af4886bdb8f4e5093068" +checksum = "7f2b9e8883d58e34b18facd16c4564a77ea50fce028ad3d0ee6753440e37acc8" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.9", @@ -4714,9 +4714,9 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" diff --git a/swap/src/bin/asb.rs b/swap/src/bin/asb.rs index 63b4c459..53bdaef2 100644 --- a/swap/src/bin/asb.rs +++ b/swap/src/bin/asb.rs @@ -15,7 +15,7 @@ use anyhow::{bail, Context, Result}; use libp2p::core::multiaddr::Protocol; use libp2p::core::Multiaddr; -use libp2p::Swarm; +use libp2p::{PeerId, Swarm}; use prettytable::{row, Table}; use std::env; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; @@ -152,6 +152,7 @@ async fn main() -> Result<()> { kraken_rate.clone(), resume_only, env_config, + seed.derive_libp2p_identity(), )?; for listen in config.network.listen { @@ -170,6 +171,7 @@ async fn main() -> Result<()> { kraken_rate.clone(), config.maker.min_buy_btc, config.maker.max_buy_btc, + PeerId::random(), ) .unwrap(); diff --git a/swap/src/network/swarm.rs b/swap/src/network/swarm.rs index 43d635d7..18367383 100644 --- a/swap/src/network/swarm.rs +++ b/swap/src/network/swarm.rs @@ -3,6 +3,7 @@ use crate::protocol::{alice, bob}; use crate::seed::Seed; use crate::{asb, bitcoin, cli, env, tor}; use anyhow::Result; +use libp2p::identity::Keypair; use libp2p::swarm::SwarmBuilder; use libp2p::{PeerId, Swarm}; use std::fmt::Debug; @@ -16,11 +17,19 @@ pub fn asb( latest_rate: LR, resume_only: bool, env_config: env::Config, + keypair: Keypair, ) -> Result>> where LR: LatestRate + Send + 'static + Debug + Clone, { - let behaviour = alice::Behaviour::new(min_buy, max_buy, latest_rate, resume_only, env_config); + let behaviour = alice::Behaviour::new( + min_buy, + max_buy, + latest_rate, + resume_only, + env_config, + keypair, + ); let identity = seed.derive_libp2p_identity(); let transport = asb::transport::new(&identity)?; diff --git a/swap/src/network/test.rs b/swap/src/network/test.rs index ea4b1a8d..a15a38ff 100644 --- a/swap/src/network/test.rs +++ b/swap/src/network/test.rs @@ -1,4 +1,5 @@ use futures::future; +use futures::stream::StreamExt; use libp2p::core::muxing::StreamMuxerBox; use libp2p::core::transport::memory::MemoryTransport; use libp2p::core::upgrade::{SelectUpgrade, Version}; @@ -129,9 +130,9 @@ where let mut bob_connected = false; while !alice_connected && !bob_connected { - let (alice_event, bob_event) = future::join(alice.next_event(), bob.next_event()).await; + let (alice_event, bob_event) = future::join(alice.next(), bob.next()).await; - match alice_event { + match alice_event.unwrap() { SwarmEvent::ConnectionEstablished { .. } => { alice_connected = true; } @@ -146,7 +147,7 @@ where } _ => {} } - match bob_event { + match bob_event.unwrap() { SwarmEvent::ConnectionEstablished { .. } => { bob_connected = true; } diff --git a/swap/src/protocol/alice/behaviour.rs b/swap/src/protocol/alice/behaviour.rs index bde934d8..6088553c 100644 --- a/swap/src/protocol/alice/behaviour.rs +++ b/swap/src/protocol/alice/behaviour.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Error}; use libp2p::ping::{Ping, PingEvent}; use libp2p::request_response::{RequestId, ResponseChannel}; -use libp2p::{NetworkBehaviour, PeerId}; +use libp2p::{rendezvous, NetworkBehaviour, PeerId}; use uuid::Uuid; use crate::env; @@ -10,6 +10,8 @@ use crate::network::{encrypted_signature, quote, transfer_proof}; use crate::protocol::alice::event_loop::LatestRate; use crate::protocol::alice::swap_setup::WalletSnapshot; use crate::protocol::alice::{swap_setup, State3}; +use libp2p::identity::Keypair; +use libp2p::rendezvous::{Event, RegisterError, Registration}; #[derive(Debug)] pub enum OutEvent { @@ -42,6 +44,13 @@ pub enum OutEvent { peer: PeerId, error: Error, }, + Registered { + rendezvous_node: PeerId, + ttl: i64, + namespace: String, + }, + RegisterFailed(RegisterError), + RegisterExpired(Registration), /// "Fallback" variant that allows the event mapping code to swallow certain /// events that we don't want the caller to deal with. Other, @@ -71,6 +80,7 @@ pub struct Behaviour where LR: LatestRate + Send + 'static, { + pub rendezvous: rendezvous::Rendezvous, pub quote: quote::Behaviour, pub swap_setup: swap_setup::Behaviour, pub transfer_proof: transfer_proof::Behaviour, @@ -92,8 +102,10 @@ where latest_rate: LR, resume_only: bool, env_config: env::Config, + keypair: Keypair, ) -> Self { Self { + rendezvous: rendezvous::Rendezvous::new(keypair, rendezvous::Config::default()), quote: quote::alice(), swap_setup: swap_setup::Behaviour::new( min_buy, @@ -114,3 +126,28 @@ impl From for OutEvent { OutEvent::Other } } + +impl From for OutEvent { + fn from(rendezvous_event: rendezvous::Event) -> Self { + match rendezvous_event { + Event::Discovered { .. } => OutEvent::Other, + Event::DiscoverFailed { .. } => OutEvent::Other, + Event::Registered { + rendezvous_node, + ttl, + namespace, + } => OutEvent::Registered { + rendezvous_node, + ttl, + namespace, + }, + Event::RegisterFailed(register_error) => OutEvent::RegisterFailed(register_error), + Event::DiscoverServed { .. } => OutEvent::Other, + Event::DiscoverNotServed { .. } => OutEvent::Other, + Event::PeerRegistered { .. } => OutEvent::Other, + Event::PeerNotRegistered { .. } => OutEvent::Other, + Event::PeerUnregistered { .. } => OutEvent::Other, + Event::RegistrationExpired(registration) => OutEvent::RegisterExpired(registration), + } + } +} diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index ad86c4da..1df96244 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -44,6 +44,7 @@ where latest_rate: LR, min_buy: bitcoin::Amount, max_buy: bitcoin::Amount, + rendezvous_node: PeerId, swap_sender: mpsc::Sender, @@ -76,6 +77,7 @@ where latest_rate: LR, min_buy: bitcoin::Amount, max_buy: bitcoin::Amount, + rendezvous_node: PeerId, ) -> Result<(Self, mpsc::Receiver)> { let swap_channel = MpscChannels::default(); @@ -89,6 +91,7 @@ where swap_sender: swap_channel.sender, min_buy, max_buy, + rendezvous_node, recv_encrypted_signature: Default::default(), inflight_encrypted_signatures: Default::default(), send_transfer_proof: Default::default(), @@ -103,6 +106,13 @@ where } pub async fn run(mut self) { + let _ = self + .swarm + .behaviour_mut() + .rendezvous + .register("xmr-btc-swap".to_string(), self.rendezvous_node, None) + .unwrap(); + // ensure that these streams are NEVER empty, otherwise it will // terminate forever. self.send_transfer_proof.push(future::pending().boxed()); @@ -268,6 +278,13 @@ where Some(SwarmEvent::NewListenAddr(address)) => { tracing::info!(%address, "New listen address detected"); } + Some(SwarmEvent::Behaviour(OutEvent::Registered { namespace, ..})) => { + tracing::info!(%namespace, "Registered with rendezvous node"); + } + Some(SwarmEvent::Behaviour(OutEvent::RegisterExpired(registration))) => { + tracing::info!("Registration expired: {:?}", ®istration); + self.swarm.behaviour_mut().rendezvous.register(registration.namespace, registration.record.peer_id(), Some(registration.ttl)).unwrap(); + } _ => {} } }, diff --git a/swap/tests/harness/mod.rs b/swap/tests/harness/mod.rs index 052b1d4b..15122ecc 100644 --- a/swap/tests/harness/mod.rs +++ b/swap/tests/harness/mod.rs @@ -156,13 +156,16 @@ async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) { .await .unwrap(); - (monero, Containers { - bitcoind_url, - bitcoind, - monerod_container, - monero_wallet_rpc_containers, - electrs, - }) + ( + monero, + Containers { + bitcoind_url, + bitcoind, + monerod_container, + monero_wallet_rpc_containers, + electrs, + }, + ) } async fn init_bitcoind_container( @@ -236,6 +239,7 @@ async fn start_alice( latest_rate, resume_only, env_config, + seed.derive_libp2p_identity(), ) .unwrap(); swarm.listen_on(listen_address).unwrap(); @@ -249,6 +253,7 @@ async fn start_alice( FixedRate::default(), min_buy, max_buy, + PeerId::random(), ) .unwrap();