From b118ffece5742949ff4bf5c1c9fcc76befb62808 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 Nov 2021 17:13:27 +1100 Subject: [PATCH 1/5] Remove maker default address This made only sense during local testing. --- .github/workflows/ci.yml | 2 +- daemon/src/taker.rs | 2 +- start_all.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83b5b69..32c38f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,7 @@ jobs: sleep 10s # Wait for maker to start\ # The maker-id is generated from the makers seed found in daemon/util/testnet_seeds/maker_seed - target/debug/taker --data-dir=/tmp/taker --maker-id 10d4ba2ac3f7a22da4009d813ff1bc3f404dfe2cc93a32bedf1512aa9951c95e testnet & + target/debug/taker --data-dir=/tmp/taker --maker localhost:9999 --maker-id 10d4ba2ac3f7a22da4009d813ff1bc3f404dfe2cc93a32bedf1512aa9951c95e testnet & sleep 10s # Wait for taker to start curl --fail http://localhost:8000/api/alive diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index 747ffac..e69d63e 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -31,7 +31,7 @@ const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(5); #[derive(Parser)] struct Opts { /// The IP address of the other party (i.e. the maker). - #[clap(long, default_value = "127.0.0.1:9999")] + #[clap(long)] maker: SocketAddr, /// The public key of the maker as a 32 byte hex string. diff --git a/start_all.sh b/start_all.sh index 5058af4..4ba1b8e 100755 --- a/start_all.sh +++ b/start_all.sh @@ -5,4 +5,4 @@ export RUST_BACKTRACE=1 # A simple command to spin up the complete package, ie. both daemons and frontends. # A single 'ctrl+c' stops all processes. # The maker-id is generated from the makers seed found in daemon/util/testnet_seeds/maker_seed -(trap 'kill 0' SIGINT; cargo run --bin maker -- testnet & cargo run --bin taker -- --maker-id 10d4ba2ac3f7a22da4009d813ff1bc3f404dfe2cc93a32bedf1512aa9951c95e testnet -- & yarn --cwd=./maker-frontend dev & yarn --cwd=./taker-frontend dev) +(trap 'kill 0' SIGINT; cargo run --bin maker -- testnet & cargo run --bin taker -- --maker localhost:9999 --maker-id 10d4ba2ac3f7a22da4009d813ff1bc3f404dfe2cc93a32bedf1512aa9951c95e testnet -- & yarn --cwd=./maker-frontend dev & yarn --cwd=./taker-frontend dev) From 97ed7ba54e505d2534c2c47d6a1c40945a6ba8d8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 Nov 2021 17:16:30 +1100 Subject: [PATCH 2/5] Extract connecting into helper function --- daemon/src/taker.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index e69d63e..cb2c66b 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -253,20 +253,7 @@ async fn main() -> Result<()> { ) .await?; - while connection_actor_addr - .send(connection::Connect { - maker_identity_pk: opts.maker_id, - maker_addr: opts.maker, - }) - .await? - .is_err() - { - sleep(CONNECTION_RETRY_INTERVAL).await; - tracing::debug!( - "Couldn't connect to the maker, retrying in {}...", - CONNECTION_RETRY_INTERVAL.as_secs() - ); - } + connect(connection_actor_addr, opts.maker_id, opts.maker).await?; tokio::spawn(wallet_sync::new(wallet, wallet_feed_sender)); let take_offer_channel = MessageChannel::::clone_channel(&cfd_actor_addr); @@ -316,3 +303,26 @@ async fn main() -> Result<()> { Ok(()) } + +async fn connect( + connection_actor_addr: xtra::Address, + maker_identity_pk: x25519_dalek::PublicKey, + maker_addr: SocketAddr, +) -> Result<()> { + while connection_actor_addr + .send(connection::Connect { + maker_identity_pk, + maker_addr, + }) + .await? + .is_err() + { + sleep(CONNECTION_RETRY_INTERVAL).await; + tracing::debug!( + "Couldn't connect to the maker, retrying in {}...", + CONNECTION_RETRY_INTERVAL.as_secs() + ); + } + + Ok(()) +} From a4c0b181cf04584fc802fde13acd74c14811611d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 Nov 2021 17:24:03 +1100 Subject: [PATCH 3/5] Allow domains for maker argument Resolving a DNS entry to a socket address can yield multiple A records. Thus we need to try all of them. Resolves #292. --- daemon/src/taker.rs | 47 +++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index cb2c66b..34aee79 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -30,9 +30,9 @@ const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(5); #[derive(Parser)] struct Opts { - /// The IP address of the other party (i.e. the maker). + /// The IP address or hostname of the other party (i.e. the maker). #[clap(long)] - maker: SocketAddr, + maker: String, /// The public key of the maker as a 32 byte hex string. #[clap(long, parse(try_from_str = parse_x25519_pubkey))] @@ -307,22 +307,41 @@ async fn main() -> Result<()> { async fn connect( connection_actor_addr: xtra::Address, maker_identity_pk: x25519_dalek::PublicKey, - maker_addr: SocketAddr, + maker_addr: String, ) -> Result<()> { - while connection_actor_addr - .send(connection::Connect { - maker_identity_pk, - maker_addr, - }) + let possible_addresses = tokio::net::lookup_host(&maker_addr) .await? - .is_err() - { - sleep(CONNECTION_RETRY_INTERVAL).await; + .collect::>(); + + tracing::debug!( + "Resolved {} to [{}]", + maker_addr, + itertools::join(possible_addresses.iter(), ",") + ); + + loop { + for address in &possible_addresses { + tracing::trace!("Connecting to {}", address); + + let connect_msg = connection::Connect { + maker_identity_pk, + maker_addr: *address, + }; + + if let Err(e) = connection_actor_addr.send(connect_msg).await? { + tracing::debug!(%address, "Failed to establish connection: {:#}", e); + continue; + } + + return Ok(()); + } + tracing::debug!( - "Couldn't connect to the maker, retrying in {}...", + "Tried connecting to {} addresses without success, retrying in {} seconds", + possible_addresses.len(), CONNECTION_RETRY_INTERVAL.as_secs() ); - } - Ok(()) + sleep(CONNECTION_RETRY_INTERVAL).await; + } } From cf5e50029c4b8a836de24a38bcd520a036ae332e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 Nov 2021 17:39:33 +1100 Subject: [PATCH 4/5] Use `TcpStream` to connect to address Not only this now automatically support IPv6, it is also shorter. --- daemon/src/connection.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/daemon/src/connection.rs b/daemon/src/connection.rs index 8b3b53a..bd51a43 100644 --- a/daemon/src/connection.rs +++ b/daemon/src/connection.rs @@ -5,6 +5,7 @@ use futures::{FutureExt, StreamExt}; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; +use tokio::net::TcpStream; use tokio::sync::watch; use tokio_util::codec::FramedRead; use xtra::prelude::MessageChannel; @@ -84,11 +85,11 @@ impl Actor { ctx: &mut xtra::Context, ) -> Result<()> { let (read, write, noise) = { - let socket = tokio::net::TcpSocket::new_v4().expect("Be able to create a socket"); - let mut connection = socket.connect(maker_addr).await?; + let mut connection = TcpStream::connect(&maker_addr).await?; let noise = noise::initiator_handshake(&mut connection, &self.identity_sk, &maker_identity_pk) .await?; + let (read, write) = connection.into_split(); (read, write, Arc::new(Mutex::new(noise))) }; From 4b85cd5704ea44ae712680a93bf7a128c38cadcf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 Nov 2021 17:58:40 +1100 Subject: [PATCH 5/5] Log establishment of connection --- daemon/src/connection.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon/src/connection.rs b/daemon/src/connection.rs index bd51a43..57bb3b8 100644 --- a/daemon/src/connection.rs +++ b/daemon/src/connection.rs @@ -118,6 +118,8 @@ impl Actor { .send(ConnectionStatus::Online) .expect("receiver to outlive the actor"); + tracing::info!(address = %maker_addr, "Established connection to maker"); + Ok(()) }