From ce077a3ff5b2a53ec859b86e7682096f059b8e1a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 3 Mar 2021 13:56:25 +1100 Subject: [PATCH] Decouple Bob's EventLoop from the builder Instead of instantiating the `EventLoop` within the builder, we only pass in the necessary arguments (which is the `EventLoopHandle`) to the Builder upon `new`. This is work towards #255 which will require us to perform network communication (which implies having the `EventLoop`) before starting a swap. --- swap/src/bin/swap_cli.rs | 48 +++++++++++++-------- swap/src/protocol/bob.rs | 83 +++++++++---------------------------- swap/tests/testutils/mod.rs | 26 ++++++++---- 3 files changed, 68 insertions(+), 89 deletions(-) diff --git a/swap/src/bin/swap_cli.rs b/swap/src/bin/swap_cli.rs index 0e75c214..ad6c74dd 100644 --- a/swap/src/bin/swap_cli.rs +++ b/swap/src/bin/swap_cli.rs @@ -31,7 +31,7 @@ use swap::{ monero::{CreateWallet, OpenWallet}, protocol::{ bob, - bob::{cancel::CancelError, Builder}, + bob::{cancel::CancelError, Builder, EventLoop}, }, seed::Seed, }; @@ -111,6 +111,7 @@ async fn main() -> Result<()> { init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?; let monero_wallet = init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?; + let bitcoin_wallet = Arc::new(bitcoin_wallet); let swap_id = Uuid::new_v4(); @@ -137,19 +138,25 @@ async fn main() -> Result<()> { let send_bitcoin = bitcoin_wallet.max_giveable(TxLock::script_size()).await?; - let bob_factory = Builder::new( - seed, + let (event_loop, event_loop_handle) = EventLoop::new( + &seed.derive_libp2p_identity(), + alice_peer_id, + alice_addr, + bitcoin_wallet.clone(), + )?; + let handle = tokio::spawn(event_loop.run()); + + let swap = Builder::new( db, swap_id, - Arc::new(bitcoin_wallet), + bitcoin_wallet.clone(), Arc::new(monero_wallet), - alice_addr, - alice_peer_id, execution_params, - ); - let (swap, event_loop) = bob_factory.with_init_params(send_bitcoin).build().await?; + event_loop_handle, + ) + .with_init_params(send_bitcoin) + .build()?; - let handle = tokio::spawn(event_loop.run()); let swap = bob::run(swap); tokio::select! { event_loop_result = handle => { @@ -181,19 +188,26 @@ async fn main() -> Result<()> { init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?; let monero_wallet = init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?; + let bitcoin_wallet = Arc::new(bitcoin_wallet); - let bob_factory = Builder::new( - seed, + let (event_loop, event_loop_handle) = EventLoop::new( + &seed.derive_libp2p_identity(), + alice_peer_id, + alice_addr, + bitcoin_wallet.clone(), + )?; + let handle = tokio::spawn(event_loop.run()); + + let swap = Builder::new( db, swap_id, - Arc::new(bitcoin_wallet), + bitcoin_wallet.clone(), Arc::new(monero_wallet), - alice_addr, - alice_peer_id, execution_params, - ); - let (swap, event_loop) = bob_factory.build().await?; - let handle = tokio::spawn(event_loop.run()); + event_loop_handle, + ) + .build()?; + let swap = bob::run(swap); tokio::select! { event_loop_result = handle => { diff --git a/swap/src/protocol/bob.rs b/swap/src/protocol/bob.rs index 3b4b8954..70ecc7d6 100644 --- a/swap/src/protocol/bob.rs +++ b/swap/src/protocol/bob.rs @@ -7,10 +7,9 @@ use crate::{ monero, network::peer_tracker::{self, PeerTracker}, protocol::{alice, alice::TransferProof, bob}, - seed::Seed, }; use anyhow::{Error, Result}; -use libp2p::{core::Multiaddr, identity::Keypair, NetworkBehaviour, PeerId}; +use libp2p::{core::Multiaddr, NetworkBehaviour, PeerId}; use std::sync::Arc; use tracing::debug; use uuid::Uuid; @@ -49,17 +48,15 @@ pub struct Swap { pub struct Builder { swap_id: Uuid, - identity: Keypair, db: Database, - alice_address: Multiaddr, - alice_peer_id: PeerId, - bitcoin_wallet: Arc, monero_wallet: Arc, init_params: InitParams, execution_params: ExecutionParams, + + event_loop_handle: bob::EventLoopHandle, } enum InitParams { @@ -70,27 +67,21 @@ enum InitParams { impl Builder { #[allow(clippy::too_many_arguments)] pub fn new( - seed: Seed, db: Database, swap_id: Uuid, bitcoin_wallet: Arc, monero_wallet: Arc, - alice_address: Multiaddr, - alice_peer_id: PeerId, execution_params: ExecutionParams, + event_loop_handle: bob::EventLoopHandle, ) -> Self { - let identity = seed.derive_libp2p_identity(); - Self { swap_id, - identity, db, - alice_address, - alice_peer_id, bitcoin_wallet, monero_wallet, init_params: InitParams::None, execution_params, + event_loop_handle, } } @@ -101,57 +92,21 @@ impl Builder { } } - pub async fn build(self) -> Result<(bob::Swap, bob::EventLoop)> { - match self.init_params { - InitParams::New { btc_amount } => { - let initial_state = BobState::Started { btc_amount }; + pub fn build(self) -> Result { + let state = match self.init_params { + InitParams::New { btc_amount } => BobState::Started { btc_amount }, + InitParams::None => self.db.get_state(self.swap_id)?.try_into_bob()?.into(), + }; - let (event_loop, event_loop_handle) = self.init_event_loop()?; - - Ok(( - Swap { - state: initial_state, - event_loop_handle, - db: self.db, - bitcoin_wallet: self.bitcoin_wallet.clone(), - monero_wallet: self.monero_wallet.clone(), - swap_id: self.swap_id, - execution_params: self.execution_params, - }, - event_loop, - )) - } - - InitParams::None => { - let resume_state = self.db.get_state(self.swap_id)?.try_into_bob()?.into(); - - let (event_loop, event_loop_handle) = self.init_event_loop()?; - - Ok(( - Swap { - state: resume_state, - event_loop_handle, - db: self.db, - bitcoin_wallet: self.bitcoin_wallet.clone(), - monero_wallet: self.monero_wallet.clone(), - swap_id: self.swap_id, - execution_params: self.execution_params, - }, - event_loop, - )) - } - } - } - - fn init_event_loop( - &self, - ) -> Result<(bob::event_loop::EventLoop, bob::event_loop::EventLoopHandle)> { - bob::event_loop::EventLoop::new( - &self.identity, - self.alice_peer_id, - self.alice_address.clone(), - self.bitcoin_wallet.clone(), - ) + Ok(Swap { + state, + event_loop_handle: self.event_loop_handle, + db: self.db, + bitcoin_wallet: self.bitcoin_wallet.clone(), + monero_wallet: self.monero_wallet.clone(), + swap_id: self.swap_id, + execution_params: self.execution_params, + }) } } diff --git a/swap/tests/testutils/mod.rs b/swap/tests/testutils/mod.rs index 844c127e..61cd01db 100644 --- a/swap/tests/testutils/mod.rs +++ b/swap/tests/testutils/mod.rs @@ -54,16 +54,23 @@ struct BobParams { } impl BobParams { - pub fn builder(&self) -> bob::Builder { + pub fn builder(&self, event_loop_handle: bob::EventLoopHandle) -> bob::Builder { bob::Builder::new( - self.seed, Database::open(&self.db_path.clone().as_path()).unwrap(), self.swap_id, self.bitcoin_wallet.clone(), self.monero_wallet.clone(), - self.alice_address.clone(), - self.alice_peer_id, self.execution_params, + event_loop_handle, + ) + } + + 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(), ) } } @@ -95,12 +102,13 @@ pub struct TestContext { impl TestContext { pub async fn new_swap_as_bob(&mut self) -> (bob::Swap, BobEventLoopJoinHandle) { - let (swap, event_loop) = self + let (event_loop, event_loop_handle) = self.bob_params.new_eventloop().unwrap(); + + let swap = self .bob_params - .builder() + .builder(event_loop_handle) .with_init_params(self.btc_amount) .build() - .await .unwrap(); let join_handle = tokio::spawn(event_loop.run()); @@ -114,7 +122,9 @@ impl TestContext { ) -> (bob::Swap, BobEventLoopJoinHandle) { join_handle.abort(); - let (swap, event_loop) = self.bob_params.builder().build().await.unwrap(); + let (event_loop, event_loop_handle) = self.bob_params.new_eventloop().unwrap(); + + let swap = self.bob_params.builder(event_loop_handle).build().unwrap(); let join_handle = tokio::spawn(event_loop.run());