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},
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 => {

View File

@ -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<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>,
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<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>,
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<bob::Swap> {
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,
})
}
}

View File

@ -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());