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.
This commit is contained in:
Thomas Eizinger 2021-03-03 13:56:25 +11:00
parent 54bc91581f
commit ce077a3ff5
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
3 changed files with 68 additions and 89 deletions

View File

@ -31,7 +31,7 @@ use swap::{
monero::{CreateWallet, OpenWallet}, monero::{CreateWallet, OpenWallet},
protocol::{ protocol::{
bob, bob,
bob::{cancel::CancelError, Builder}, bob::{cancel::CancelError, Builder, EventLoop},
}, },
seed::Seed, seed::Seed,
}; };
@ -111,6 +111,7 @@ async fn main() -> Result<()> {
init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?; init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?;
let monero_wallet = let monero_wallet =
init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?; init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?;
let bitcoin_wallet = Arc::new(bitcoin_wallet);
let swap_id = Uuid::new_v4(); 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 send_bitcoin = bitcoin_wallet.max_giveable(TxLock::script_size()).await?;
let bob_factory = Builder::new( let (event_loop, event_loop_handle) = EventLoop::new(
seed, &seed.derive_libp2p_identity(),
alice_peer_id,
alice_addr,
bitcoin_wallet.clone(),
)?;
let handle = tokio::spawn(event_loop.run());
let swap = Builder::new(
db, db,
swap_id, swap_id,
Arc::new(bitcoin_wallet), bitcoin_wallet.clone(),
Arc::new(monero_wallet), Arc::new(monero_wallet),
alice_addr,
alice_peer_id,
execution_params, execution_params,
); event_loop_handle,
let (swap, event_loop) = bob_factory.with_init_params(send_bitcoin).build().await?; )
.with_init_params(send_bitcoin)
.build()?;
let handle = tokio::spawn(event_loop.run());
let swap = bob::run(swap); let swap = bob::run(swap);
tokio::select! { tokio::select! {
event_loop_result = handle => { event_loop_result = handle => {
@ -181,19 +188,26 @@ async fn main() -> Result<()> {
init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?; init_bitcoin_wallet(config, bitcoin_network, &wallet_data_dir, seed).await?;
let monero_wallet = let monero_wallet =
init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?; init_monero_wallet(monero_network, monero_wallet_rpc_process.endpoint()).await?;
let bitcoin_wallet = Arc::new(bitcoin_wallet);
let bob_factory = Builder::new( let (event_loop, event_loop_handle) = EventLoop::new(
seed, &seed.derive_libp2p_identity(),
alice_peer_id,
alice_addr,
bitcoin_wallet.clone(),
)?;
let handle = tokio::spawn(event_loop.run());
let swap = Builder::new(
db, db,
swap_id, swap_id,
Arc::new(bitcoin_wallet), bitcoin_wallet.clone(),
Arc::new(monero_wallet), Arc::new(monero_wallet),
alice_addr,
alice_peer_id,
execution_params, execution_params,
); event_loop_handle,
let (swap, event_loop) = bob_factory.build().await?; )
let handle = tokio::spawn(event_loop.run()); .build()?;
let swap = bob::run(swap); let swap = bob::run(swap);
tokio::select! { tokio::select! {
event_loop_result = handle => { event_loop_result = handle => {

View File

@ -7,10 +7,9 @@ use crate::{
monero, monero,
network::peer_tracker::{self, PeerTracker}, network::peer_tracker::{self, PeerTracker},
protocol::{alice, alice::TransferProof, bob}, protocol::{alice, alice::TransferProof, bob},
seed::Seed,
}; };
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use libp2p::{core::Multiaddr, identity::Keypair, NetworkBehaviour, PeerId}; use libp2p::{core::Multiaddr, NetworkBehaviour, PeerId};
use std::sync::Arc; use std::sync::Arc;
use tracing::debug; use tracing::debug;
use uuid::Uuid; use uuid::Uuid;
@ -49,17 +48,15 @@ pub struct Swap {
pub struct Builder { pub struct Builder {
swap_id: Uuid, swap_id: Uuid,
identity: Keypair,
db: Database, db: Database,
alice_address: Multiaddr,
alice_peer_id: PeerId,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, monero_wallet: Arc<monero::Wallet>,
init_params: InitParams, init_params: InitParams,
execution_params: ExecutionParams, execution_params: ExecutionParams,
event_loop_handle: bob::EventLoopHandle,
} }
enum InitParams { enum InitParams {
@ -70,27 +67,21 @@ enum InitParams {
impl Builder { impl Builder {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
seed: Seed,
db: Database, db: Database,
swap_id: Uuid, swap_id: Uuid,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, monero_wallet: Arc<monero::Wallet>,
alice_address: Multiaddr,
alice_peer_id: PeerId,
execution_params: ExecutionParams, execution_params: ExecutionParams,
event_loop_handle: bob::EventLoopHandle,
) -> Self { ) -> Self {
let identity = seed.derive_libp2p_identity();
Self { Self {
swap_id, swap_id,
identity,
db, db,
alice_address,
alice_peer_id,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, monero_wallet,
init_params: InitParams::None, init_params: InitParams::None,
execution_params, execution_params,
event_loop_handle,
} }
} }
@ -101,57 +92,21 @@ impl Builder {
} }
} }
pub async fn build(self) -> Result<(bob::Swap, bob::EventLoop)> { pub fn build(self) -> Result<bob::Swap> {
match self.init_params { let state = match self.init_params {
InitParams::New { btc_amount } => { InitParams::New { btc_amount } => BobState::Started { btc_amount },
let initial_state = 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,
Ok(( event_loop_handle: self.event_loop_handle,
Swap { db: self.db,
state: initial_state, bitcoin_wallet: self.bitcoin_wallet.clone(),
event_loop_handle, monero_wallet: self.monero_wallet.clone(),
db: self.db, swap_id: self.swap_id,
bitcoin_wallet: self.bitcoin_wallet.clone(), execution_params: self.execution_params,
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(),
)
} }
} }

View File

@ -54,16 +54,23 @@ struct BobParams {
} }
impl BobParams { impl BobParams {
pub fn builder(&self) -> bob::Builder { pub fn builder(&self, event_loop_handle: bob::EventLoopHandle) -> bob::Builder {
bob::Builder::new( bob::Builder::new(
self.seed,
Database::open(&self.db_path.clone().as_path()).unwrap(), Database::open(&self.db_path.clone().as_path()).unwrap(),
self.swap_id, self.swap_id,
self.bitcoin_wallet.clone(), self.bitcoin_wallet.clone(),
self.monero_wallet.clone(), self.monero_wallet.clone(),
self.alice_address.clone(),
self.alice_peer_id,
self.execution_params, 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 { impl TestContext {
pub async fn new_swap_as_bob(&mut self) -> (bob::Swap, BobEventLoopJoinHandle) { 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 .bob_params
.builder() .builder(event_loop_handle)
.with_init_params(self.btc_amount) .with_init_params(self.btc_amount)
.build() .build()
.await
.unwrap(); .unwrap();
let join_handle = tokio::spawn(event_loop.run()); let join_handle = tokio::spawn(event_loop.run());
@ -114,7 +122,9 @@ impl TestContext {
) -> (bob::Swap, BobEventLoopJoinHandle) { ) -> (bob::Swap, BobEventLoopJoinHandle) {
join_handle.abort(); 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()); let join_handle = tokio::spawn(event_loop.run());