From 2200fce3f3e9f02d26aba4eb4dc739c9153745bf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 23 Mar 2021 16:56:04 +1100 Subject: [PATCH] Pass Swarm into EventLoop This reduces the amount of arguments we need to pass into the eventloop at the expense of slightly more setup of the swarm. --- swap/src/bin/asb.rs | 11 ++++++++--- swap/src/bin/swap.rs | 26 +++++++++++++------------- swap/src/network.rs | 17 +---------------- swap/src/network/swarm.rs | 23 +++++++++++++++++++++++ swap/src/protocol/alice/event_loop.rs | 26 +++----------------------- swap/src/protocol/bob/event_loop.rs | 23 +++-------------------- swap/tests/testutils/mod.rs | 19 ++++++++++--------- 7 files changed, 61 insertions(+), 84 deletions(-) create mode 100644 swap/src/network/swarm.rs diff --git a/swap/src/bin/asb.rs b/swap/src/bin/asb.rs index b148ced7..b8a00da8 100644 --- a/swap/src/bin/asb.rs +++ b/swap/src/bin/asb.rs @@ -15,6 +15,7 @@ use anyhow::{Context, Result}; use bdk::descriptor::Segwitv0; use bdk::keys::DerivableKey; +use libp2p::Swarm; use prettytable::{row, Table}; use std::path::Path; use std::sync::Arc; @@ -27,7 +28,8 @@ use swap::database::Database; use swap::env::GetConfig; use swap::fs::default_config_path; use swap::monero::Amount; -use swap::protocol::alice::{run, EventLoop}; +use swap::network::swarm; +use swap::protocol::alice::{run, Behaviour, EventLoop}; use swap::seed::Seed; use swap::trace::init_tracing; use swap::{bitcoin, env, kraken, monero}; @@ -93,9 +95,12 @@ async fn main() -> Result<()> { let kraken_rate_updates = kraken::connect()?; + let mut swarm = swarm::new::(&seed)?; + Swarm::listen_on(&mut swarm, config.network.listen) + .context("Failed to listen network interface")?; + let (event_loop, mut swap_receiver) = EventLoop::new( - config.network.listen, - seed, + swarm, env_config, Arc::new(bitcoin_wallet), Arc::new(monero_wallet), diff --git a/swap/src/bin/swap.rs b/swap/src/bin/swap.rs index 8af25443..da3d2a23 100644 --- a/swap/src/bin/swap.rs +++ b/swap/src/bin/swap.rs @@ -25,8 +25,9 @@ use swap::cli::command::{AliceConnectParams, Arguments, Command, Data, MoneroPar use swap::database::Database; use swap::env::{Config, GetConfig}; use swap::network::quote::BidQuote; +use swap::network::swarm; use swap::protocol::bob; -use swap::protocol::bob::{Builder, EventLoop}; +use swap::protocol::bob::{Behaviour, Builder, EventLoop}; use swap::seed::Seed; use swap::{bitcoin, env, monero}; use tracing::{debug, error, info, warn, Level}; @@ -105,12 +106,12 @@ async fn main() -> Result<()> { let (monero_wallet, _process) = init_monero_wallet(data_dir, monero_daemon_host, env_config).await?; let bitcoin_wallet = Arc::new(bitcoin_wallet); - let (event_loop, mut event_loop_handle) = EventLoop::new( - &seed.derive_libp2p_identity(), - alice_peer_id, - alice_addr, - bitcoin_wallet.clone(), - )?; + + let mut swarm = swarm::new::(&seed)?; + swarm.add_address(alice_peer_id, alice_addr); + + let (event_loop, mut event_loop_handle) = + EventLoop::new(swarm, alice_peer_id, bitcoin_wallet.clone())?; let event_loop = tokio::spawn(event_loop.run()); let send_bitcoin = determine_btc_to_swap( @@ -189,12 +190,11 @@ async fn main() -> Result<()> { init_monero_wallet(data_dir, monero_daemon_host, env_config).await?; let bitcoin_wallet = Arc::new(bitcoin_wallet); - let (event_loop, event_loop_handle) = EventLoop::new( - &seed.derive_libp2p_identity(), - alice_peer_id, - alice_addr, - bitcoin_wallet.clone(), - )?; + let mut swarm = swarm::new::(&seed)?; + swarm.add_address(alice_peer_id, alice_addr); + + let (event_loop, event_loop_handle) = + EventLoop::new(swarm, alice_peer_id, bitcoin_wallet.clone())?; let handle = tokio::spawn(event_loop.run()); let swap = Builder::new( diff --git a/swap/src/network.rs b/swap/src/network.rs index 388cd1e0..f279fb50 100644 --- a/swap/src/network.rs +++ b/swap/src/network.rs @@ -3,21 +3,6 @@ pub mod encrypted_signature; pub mod peer_tracker; pub mod quote; pub mod spot_price; +pub mod swarm; pub mod transfer_proof; pub mod transport; - -use libp2p::core::Executor; -use std::future::Future; -use std::pin::Pin; -use tokio::runtime::Handle; - -#[allow(missing_debug_implementations)] -pub struct TokioExecutor { - pub handle: Handle, -} - -impl Executor for TokioExecutor { - fn exec(&self, future: Pin + Send>>) { - let _ = self.handle.spawn(future); - } -} diff --git a/swap/src/network/swarm.rs b/swap/src/network/swarm.rs new file mode 100644 index 00000000..40e9f6d4 --- /dev/null +++ b/swap/src/network/swarm.rs @@ -0,0 +1,23 @@ +use crate::network::transport; +use crate::seed::Seed; +use anyhow::Result; +use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; +use libp2p::Swarm; + +pub fn new(seed: &Seed) -> Result> +where + B: NetworkBehaviour + Default, +{ + let identity = seed.derive_libp2p_identity(); + + let behaviour = B::default(); + let transport = transport::build(&identity)?; + + let swarm = SwarmBuilder::new(transport, behaviour, identity.public().into_peer_id()) + .executor(Box::new(|f| { + tokio::spawn(f); + })) + .build(); + + Ok(swarm) +} diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index 1b7e195c..dcc6f638 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -3,15 +3,13 @@ use crate::database::Database; use crate::env::Config; use crate::monero::BalanceTooLow; use crate::network::quote::BidQuote; -use crate::network::{encrypted_signature, spot_price, transfer_proof, transport, TokioExecutor}; +use crate::network::{encrypted_signature, spot_price, transfer_proof}; use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State3, Swap}; -use crate::seed::Seed; use crate::{bitcoin, kraken, monero}; use anyhow::{bail, Context, Result}; use futures::future; use futures::future::{BoxFuture, FutureExt}; use futures::stream::{FuturesUnordered, StreamExt}; -use libp2p::core::Multiaddr; use libp2p::{PeerId, Swarm}; use rand::rngs::OsRng; use std::collections::HashMap; @@ -24,7 +22,6 @@ use uuid::Uuid; #[allow(missing_debug_implementations)] pub struct EventLoop { swarm: libp2p::Swarm, - peer_id: PeerId, env_config: Config, bitcoin_wallet: Arc, monero_wallet: Arc, @@ -46,10 +43,8 @@ impl EventLoop where LR: LatestRate, { - #[allow(clippy::too_many_arguments)] pub fn new( - listen_address: Multiaddr, - seed: Seed, + swarm: Swarm, env_config: Config, bitcoin_wallet: Arc, monero_wallet: Arc, @@ -57,25 +52,10 @@ where latest_rate: LR, max_buy: bitcoin::Amount, ) -> Result<(Self, mpsc::Receiver)> { - let identity = seed.derive_libp2p_identity(); - let behaviour = Behaviour::default(); - let transport = transport::build(&identity)?; - let peer_id = PeerId::from(identity.public()); - - let mut swarm = libp2p::swarm::SwarmBuilder::new(transport, behaviour, peer_id) - .executor(Box::new(TokioExecutor { - handle: tokio::runtime::Handle::current(), - })) - .build(); - - Swarm::listen_on(&mut swarm, listen_address.clone()) - .with_context(|| format!("Address is not supported: {:#}", listen_address))?; - let swap_channel = MpscChannels::default(); let event_loop = EventLoop { swarm, - peer_id, env_config, bitcoin_wallet, monero_wallet, @@ -90,7 +70,7 @@ where } pub fn peer_id(&self) -> PeerId { - self.peer_id + *Swarm::local_peer_id(&self.swarm) } pub async fn run(mut self) { diff --git a/swap/src/protocol/bob/event_loop.rs b/swap/src/protocol/bob/event_loop.rs index 47c7c195..16472190 100644 --- a/swap/src/protocol/bob/event_loop.rs +++ b/swap/src/protocol/bob/event_loop.rs @@ -1,12 +1,11 @@ use crate::bitcoin::EncryptedSignature; use crate::network::quote::BidQuote; -use crate::network::{spot_price, transfer_proof, transport, TokioExecutor}; +use crate::network::{spot_price, transfer_proof}; use crate::protocol::bob::{Behaviour, OutEvent, State0, State2}; use crate::{bitcoin, monero}; use anyhow::{anyhow, bail, Context, Result}; use futures::FutureExt; -use libp2p::core::Multiaddr; -use libp2p::PeerId; +use libp2p::{PeerId, Swarm}; use std::convert::Infallible; use std::sync::Arc; use tokio::sync::mpsc::{Receiver, Sender}; @@ -131,26 +130,10 @@ pub struct EventLoop { impl EventLoop { pub fn new( - identity: &libp2p::core::identity::Keypair, + swarm: Swarm, alice_peer_id: PeerId, - alice_addr: Multiaddr, bitcoin_wallet: Arc, ) -> Result<(Self, EventLoopHandle)> { - let behaviour = Behaviour::default(); - let transport = transport::build(identity)?; - - let mut swarm = libp2p::swarm::SwarmBuilder::new( - transport, - behaviour, - identity.public().into_peer_id(), - ) - .executor(Box::new(TokioExecutor { - handle: tokio::runtime::Handle::current(), - })) - .build(); - - swarm.add_address(alice_peer_id, alice_addr); - let start_execution_setup = Channels::new(); let done_execution_setup = Channels::new(); let recv_transfer_proof = Channels::new(); diff --git a/swap/tests/testutils/mod.rs b/swap/tests/testutils/mod.rs index d22fc2e9..1235462e 100644 --- a/swap/tests/testutils/mod.rs +++ b/swap/tests/testutils/mod.rs @@ -7,7 +7,7 @@ use bitcoin_harness::{BitcoindRpcApi, Client}; use futures::Future; use get_port::get_port; use libp2p::core::Multiaddr; -use libp2p::PeerId; +use libp2p::{PeerId, Swarm}; use monero_harness::{image, Monero}; use std::convert::Infallible; use std::path::{Path, PathBuf}; @@ -17,6 +17,7 @@ use swap::asb::FixedRate; use swap::bitcoin::{CancelTimelock, PunishTimelock}; use swap::database::Database; use swap::env::{Config, GetConfig}; +use swap::network::swarm; use swap::protocol::alice::{AliceState, Swap}; use swap::protocol::bob::BobState; use swap::protocol::{alice, bob}; @@ -70,12 +71,10 @@ impl BobParams { } pub fn new_eventloop(&self) -> Result<(bob::EventLoop, bob::EventLoopHandle)> { - bob::EventLoop::new( - &self.seed.derive_libp2p_identity(), - self.alice_peer_id, - self.alice_address.clone(), - self.bitcoin_wallet.clone(), - ) + let mut swarm = swarm::new::(&self.seed)?; + swarm.add_address(self.alice_peer_id, self.alice_address.clone()); + + bob::EventLoop::new(swarm, self.alice_peer_id, self.bitcoin_wallet.clone()) } } @@ -384,9 +383,11 @@ where ) .await; + let mut alice_swarm = swarm::new::(&alice_seed).unwrap(); + Swarm::listen_on(&mut alice_swarm, alice_listen_address.clone()).unwrap(); + let (alice_event_loop, alice_swap_handle) = alice::EventLoop::new( - alice_listen_address.clone(), - alice_seed, + alice_swarm, env_config, alice_bitcoin_wallet.clone(), alice_monero_wallet.clone(),