diff --git a/swap/src/api/request.rs b/swap/src/api/request.rs index c6f63c06..cb5d58af 100644 --- a/swap/src/api/request.rs +++ b/swap/src/api/request.rs @@ -309,6 +309,54 @@ impl Request { monero_receive_address, swap_id, } => { + let bitcoin_wallet = Arc::clone( + context + .bitcoin_wallet + .as_ref() + .expect("Could not find Bitcoin wallet"), + ); + let monero_wallet = Arc::clone( + context + .monero_wallet + .as_ref() + .context("Could not get Monero wallet")?, + ); + let env_config = context.config.env_config; + let seed = context.config.seed.clone().context("Could not get seed")?; + + let seller_peer_id = seller + .extract_peer_id() + .context("Seller address must contain peer ID")?; + context + .db + .insert_address(seller_peer_id, seller.clone()) + .await?; + + let behaviour = cli::Behaviour::new( + seller_peer_id, + env_config, + bitcoin_wallet.clone(), + (seed.derive_libp2p_identity(), context.config.namespace), + ); + let mut swarm = swarm::cli( + seed.derive_libp2p_identity(), + context + .config + .tor_socks5_port + .context("Could not get Tor SOCKS5 port")?, + behaviour, + ) + .await?; + + swarm.behaviour_mut().add_address(seller_peer_id, seller); + + context + .db + .insert_monero_address(swap_id, monero_receive_address) + .await?; + + tracing::debug!(peer_id = %swarm.local_peer_id(), "Network layer initialized"); + context.swap_lock.acquire_swap_lock(swap_id).await?; let initialize_swap = tokio::select! { @@ -319,102 +367,19 @@ impl Request { bail!("Shutdown signal received"); }, result = async { - let bitcoin_wallet = Arc::clone( - context - .bitcoin_wallet - .as_ref() - .expect("Could not find Bitcoin wallet"), - ); - let env_config = context.config.env_config; - let seed = context.config.seed.clone().context("Could not get seed")?; - - let seller_peer_id = seller - .extract_peer_id() - .context("Seller address must contain peer ID")?; - context - .db - .insert_address(seller_peer_id, seller.clone()) - .await?; - - let behaviour = cli::Behaviour::new( - seller_peer_id, - env_config, - bitcoin_wallet.clone(), - (seed.derive_libp2p_identity(), context.config.namespace), - ); - let mut swarm = swarm::cli( - seed.derive_libp2p_identity(), - context - .config - .tor_socks5_port - .context("Could not get Tor SOCKS5 port")?, - behaviour, - ) - .await?; - swarm.behaviour_mut().add_address(seller_peer_id, seller); - - tracing::debug!(peer_id = %swarm.local_peer_id(), "Network layer initialized"); - let (event_loop, mut event_loop_handle) = EventLoop::new(swap_id, swarm, seller_peer_id)?; let event_loop = tokio::spawn(event_loop.run().in_current_span()); + let bid_quote = event_loop_handle.request_quote().await?; - let max_givable = || bitcoin_wallet.max_giveable(TxLock::script_size()); - let estimate_fee = |amount| bitcoin_wallet.estimate_fee(TxLock::weight(), amount); - let determine_amount = determine_btc_to_swap( - context.config.json, - event_loop_handle.request_quote(), - bitcoin_wallet.new_address(), - || bitcoin_wallet.balance(), - max_givable, - || bitcoin_wallet.sync(), - estimate_fee, - ); - - - let (amount, fees) = match determine_amount.await { - Ok(val) => val, - Err(error) => match error.downcast::() { - Ok(_) => { - bail!("Seller's XMR balance is currently too low to initiate a swap, please try again later") - } - Err(other) => bail!(other), - }, - }; - - tracing::info!(%amount, %fees, "Determined swap amount"); - - context.db.insert_peer_id(swap_id, seller_peer_id).await?; - - context - .db - .insert_monero_address(swap_id, monero_receive_address) - .await?; - let monero_wallet = context - .monero_wallet - .as_ref() - .context("Could not get Monero wallet")?; - - let swap = Swap::new( - Arc::clone(&context.db), - swap_id, - Arc::clone(&bitcoin_wallet), - Arc::clone(monero_wallet), - env_config, - event_loop_handle, - monero_receive_address, - bitcoin_change_address, - amount, - ); - - Ok((event_loop,swap)) + Ok::<_, anyhow::Error>((event_loop, event_loop_handle, bid_quote)) } => { result }, }; - let (event_loop, swap) = match initialize_swap { - Ok((event_loop, swap)) => (event_loop, swap), + let (event_loop, event_loop_handle, bid_quote) = match initialize_swap { + Ok(result) => result, Err(error) => { tracing::error!(%swap_id, "Swap initialization failed: {:#}", error); context @@ -434,7 +399,6 @@ impl Request { context.swap_lock.release_swap_lock().await.expect("Shutdown signal received but failed to release swap lock. The swap process has been terminated but the swap lock is still active."); bail!("Shutdown signal received"); }, - event_loop_result = event_loop => { match event_loop_result { Ok(_) => { @@ -445,7 +409,48 @@ impl Request { } } }, - swap_result = bob::run(swap) => { + swap_result = async { + let max_givable = || bitcoin_wallet.max_giveable(TxLock::script_size()); + let estimate_fee = |amount| bitcoin_wallet.estimate_fee(TxLock::weight(), amount); + + let determine_amount = determine_btc_to_swap( + context.config.json, + bid_quote, + bitcoin_wallet.new_address(), + || bitcoin_wallet.balance(), + max_givable, + || bitcoin_wallet.sync(), + estimate_fee, + ); + + let (amount, fees) = match determine_amount.await { + Ok(val) => val, + Err(error) => match error.downcast::() { + Ok(_) => { + bail!("Seller's XMR balance is currently too low to initiate a swap, please try again later") + } + Err(other) => bail!(other), + }, + }; + + tracing::info!(%amount, %fees, "Determined swap amount"); + + context.db.insert_peer_id(swap_id, seller_peer_id).await?; + + let swap = Swap::new( + Arc::clone(&context.db), + swap_id, + Arc::clone(&bitcoin_wallet), + monero_wallet, + env_config, + event_loop_handle, + monero_receive_address, + bitcoin_change_address, + amount, + ); + + bob::run(swap).await + } => { match swap_result { Ok(state) => { tracing::debug!(%swap_id, state=%state, "Swap completed") @@ -814,7 +819,7 @@ fn qr_code(value: &impl ToString) -> Result { pub async fn determine_btc_to_swap( json: bool, - bid_quote: impl Future>, + bid_quote: BidQuote, get_new_address: impl Future>, balance: FB, max_giveable_fn: FMG, @@ -831,9 +836,6 @@ where FFE: Fn(Amount) -> TFE, TFE: Future>, { - tracing::debug!("Requesting quote"); - let bid_quote = bid_quote.await?; - if bid_quote.max_quantity == Amount::ZERO { bail!(ZeroQuoteReceived) } diff --git a/swap/src/bin/swap.rs b/swap/src/bin/swap.rs index 9e8ebbc5..a3c2a30f 100644 --- a/swap/src/bin/swap.rs +++ b/swap/src/bin/swap.rs @@ -56,7 +56,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_max(0.01)) }, + quote_with_max(0.01), get_dummy_address(), || async { Ok(Amount::from_btc(0.001)?) }, || async { @@ -93,7 +93,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_max(0.01)) }, + quote_with_max(0.01), get_dummy_address(), || async { Ok(Amount::from_btc(0.1001)?) }, || async { @@ -130,7 +130,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_max(0.01)) }, + quote_with_max(0.01), async { panic!("should not request new address when initial balance is > 0") }, || async { Ok(Amount::from_btc(0.005)?) }, || async { @@ -163,7 +163,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_max(0.01)) }, + quote_with_max(0.01), async { panic!("should not request new address when initial balance is > 0") }, || async { Ok(Amount::from_btc(0.1001)?) }, || async { @@ -196,7 +196,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_min(0.01)) }, + quote_with_min(0.01), get_dummy_address(), || async { Ok(Amount::from_btc(0.0101)?) }, || async { @@ -233,7 +233,7 @@ mod tests { let (amount, fees) = determine_btc_to_swap( true, - async { Ok(quote_with_min(0.01)) }, + quote_with_min(0.01), get_dummy_address(), || async { Ok(Amount::from_btc(0.0101)?) }, || async { @@ -275,7 +275,7 @@ mod tests { Duration::from_secs(1), determine_btc_to_swap( true, - async { Ok(quote_with_min(0.1)) }, + quote_with_min(0.1), get_dummy_address(), || async { Ok(Amount::from_btc(0.0101)?) }, || async { @@ -323,7 +323,7 @@ mod tests { Duration::from_secs(10), determine_btc_to_swap( true, - async { Ok(quote_with_min(0.1)) }, + quote_with_min(0.1), get_dummy_address(), || async { Ok(Amount::from_btc(0.21)?) }, || async { @@ -358,7 +358,7 @@ mod tests { let determination_error = determine_btc_to_swap( true, - async { Ok(quote_with_max(0.00)) }, + quote_with_max(0.00), get_dummy_address(), || async { Ok(Amount::from_btc(0.0101)?) }, || async { diff --git a/swap/src/cli/event_loop.rs b/swap/src/cli/event_loop.rs index 1799d20b..5217b688 100644 --- a/swap/src/cli/event_loop.rs +++ b/swap/src/cli/event_loop.rs @@ -241,6 +241,7 @@ impl EventLoopHandle { } pub async fn request_quote(&mut self) -> Result { + tracing::debug!("Requesting quote"); Ok(self.quote.send_receive(()).await?) }