Return error to API caller if bid quote request fails

This commit is contained in:
binarybaron 2023-11-08 22:41:30 +01:00
parent f9912b66da
commit b51b0e02d6
3 changed files with 105 additions and 102 deletions

View file

@ -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::<ZeroQuoteReceived>() {
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::<ZeroQuoteReceived>() {
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<String> {
pub async fn determine_btc_to_swap<FB, TB, FMG, TMG, FS, TS, FFE, TFE>(
json: bool,
bid_quote: impl Future<Output = Result<BidQuote>>,
bid_quote: BidQuote,
get_new_address: impl Future<Output = Result<bitcoin::Address>>,
balance: FB,
max_giveable_fn: FMG,
@ -831,9 +836,6 @@ where
FFE: Fn(Amount) -> TFE,
TFE: Future<Output = Result<Amount>>,
{
tracing::debug!("Requesting quote");
let bid_quote = bid_quote.await?;
if bid_quote.max_quantity == Amount::ZERO {
bail!(ZeroQuoteReceived)
}