diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index 766cbc4..216744e 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -39,7 +39,7 @@ url = "2.5.0" futures-util = { version = "0.3.28", default-features = false, features = ["sink", "std"] } async-trait = "0.1.80" hex = "0.4" -reqwest = { version = "=0.11.20", features = ["json", "blocking"] } +reqwest = { version = "=0.11.20", features = ["json"] } electrum-client = { version = "0.19.0" } [dev-dependencies] diff --git a/lib/core/src/chain/liquid.rs b/lib/core/src/chain/liquid.rs index 3bb041f..dd9946f 100644 --- a/lib/core/src/chain/liquid.rs +++ b/lib/core/src/chain/liquid.rs @@ -36,8 +36,6 @@ struct EsploraTx { status: Status, } -// TODO some of this fields may be Option in unconfirmed - #[derive(Deserialize)] struct Status { block_height: Option, @@ -64,7 +62,7 @@ impl LiquidChainService for HybridLiquidChainService { async fn broadcast(&self, tx: &Transaction, swap_id: Option<&str>) -> Result { let tx_bytes = tx.serialize(); - info!("tx: {}", tx_bytes.to_hex()); + info!("Broadcasting Liquid tx: {}", tx_bytes.to_hex()); let client = reqwest::Client::new(); let response = client .post(format!("{LIQUID_ESPLORA_URL}/tx")) diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index 995e539..a56de90 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -18,7 +18,7 @@ use crate::receive_swap::{ }; use crate::utils; -pub const LOWBALL_FEE_RATE: f32 = 0.01; +pub const LOWBALL_FEE_RATE_SAT_PER_VBYTE: f32 = 0.01; /// Configuration for the Liquid SDK #[derive(Clone, Debug, Serialize)] diff --git a/lib/core/src/receive_swap.rs b/lib/core/src/receive_swap.rs index f642a1e..7a41f5f 100644 --- a/lib/core/src/receive_swap.rs +++ b/lib/core/src/receive_swap.rs @@ -98,7 +98,10 @@ impl ReceiveSwapStateHandler { } // looking for lockup script history to verify lockup was broadcasted - if let Err(e) = self.verify_lockup_tx(&receive_swap, &transaction).await { + if let Err(e) = self + .verify_lockup_tx(&receive_swap, &transaction, false) + .await + { return Err(anyhow!( "swapper mempool reported lockup could not be verified. txid: {}, err: {}", transaction.id, @@ -164,7 +167,10 @@ impl ReceiveSwapStateHandler { return Err(anyhow!("Unexpected payload from Boltz status stream")); }; // looking for lockup script history to verify lockup was broadcasted - if let Err(e) = self.verify_lockup_tx(&receive_swap, &transaction).await { + if let Err(e) = self + .verify_lockup_tx(&receive_swap, &transaction, true) + .await + { return Err(anyhow!( "swapper reported lockup could not be verified. txid: {}, err: {}", transaction.id, @@ -306,6 +312,7 @@ impl ReceiveSwapStateHandler { &self, receive_swap: &ReceiveSwap, swap_update_tx: &SwapUpdateTxDetails, + verify_confirmation: bool, ) -> Result<()> { // looking for lockup script history to verify lockup was broadcasted let script_history = self.lockup_script_history(receive_swap).await?; @@ -313,28 +320,38 @@ impl ReceiveSwapStateHandler { .iter() .find(|h| h.txid.to_hex().eq(&swap_update_tx.id)); - if lockup_tx_history.is_none() { - return Err(anyhow!( - "swapper lockup wasn't found, reported txid={} waiting for confirmation", - swap_update_tx.id, - )); - } + match lockup_tx_history { + Some(history) => { + info!("swapper lockup found, verifying transaction content..."); - info!("swapper lockup found, verifying transaction content..."); + let lockup_tx = utils::deserialize_tx_hex(&swap_update_tx.hex)?; + if !lockup_tx + .txid() + .to_hex() + .eq(&lockup_tx_history.unwrap().txid.to_hex()) + { + return Err(anyhow!( + "swapper reported txid and transaction hex do not match: {} vs {}", + swap_update_tx.id, + lockup_tx.txid().to_hex() + )); + } - let lockup_tx = utils::deserialize_tx_hex(&swap_update_tx.hex)?; - if !lockup_tx - .txid() - .to_hex() - .eq(&lockup_tx_history.unwrap().txid.to_hex()) - { - return Err(anyhow!( - "swapper reported txid and transaction hex do not match: {} vs {}", - swap_update_tx.id, - lockup_tx.txid().to_hex() - )); + if verify_confirmation && history.height <= 0 { + return Err(anyhow!( + "swapper reported lockup was not confirmed, txid={} waiting for confirmation", + swap_update_tx.id, + )); + } + Ok(()) + } + None => { + return Err(anyhow!( + "swapper reported lockup wasn't found, txid={} waiting for confirmation", + swap_update_tx.id, + )); + } } - Ok(()) } async fn lockup_script_history(&self, receive_swap: &ReceiveSwap) -> Result> { diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index 98cdb3b..5bbff0f 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -565,7 +565,11 @@ impl LiquidSdk { async fn estimate_onchain_tx_fee(&self, amount_sat: u64, address: &str) -> Result { Ok(self .onchain_wallet - .build_tx(Some(LOWBALL_FEE_RATE * 1000.0), address, amount_sat) + .build_tx( + Some(LOWBALL_FEE_RATE_SAT_PER_VBYTE * 1000.0), + address, + amount_sat, + ) .await? .all_fees() .values() diff --git a/lib/core/src/send_swap.rs b/lib/core/src/send_swap.rs index 8bce0b1..de347c9 100644 --- a/lib/core/src/send_swap.rs +++ b/lib/core/src/send_swap.rs @@ -13,7 +13,7 @@ use tokio::sync::{broadcast, Mutex}; use crate::chain::liquid::LiquidChainService; use crate::model::PaymentState::{Complete, Created, Failed, Pending, TimedOut}; -use crate::model::{Config, SendSwap, LOWBALL_FEE_RATE}; +use crate::model::{Config, SendSwap, LOWBALL_FEE_RATE_SAT_PER_VBYTE}; use crate::swapper::Swapper; use crate::wallet::OnchainWallet; use crate::{ensure_sdk, get_invoice_amount}; @@ -196,7 +196,7 @@ impl SendSwapStateHandler { let lockup_tx = self .onchain_wallet .build_tx( - Some(LOWBALL_FEE_RATE * 1000.0), + Some(LOWBALL_FEE_RATE_SAT_PER_VBYTE * 1000.0), &create_response.address, create_response.expected_amount, )