Skip to content

Commit

Permalink
Zero-amount quote get balance retry (#603)
Browse files Browse the repository at this point in the history
* Use non-blocking sleep

* Use script_get_balance_with_retry to get user lockup balance
  • Loading branch information
dangeross authored Dec 13, 2024
1 parent a57083f commit e3fa3d6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 41 additions & 2 deletions lib/core/src/chain/bitcoin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::thread;
use std::time::Duration;

use anyhow::{anyhow, Result};
Expand Down Expand Up @@ -56,6 +55,13 @@ pub trait BitcoinChainService: Send + Sync {
/// Return the confirmed and unconfirmed balances of a list of script hashes
fn scripts_get_balance(&self, scripts: &[&Script]) -> Result<Vec<GetBalanceRes>>;

/// Return the confirmed and unconfirmed balances of a script hash
async fn script_get_balance_with_retry(
&self,
script: &Script,
retries: u64,
) -> Result<GetBalanceRes>;

/// Verify that a transaction appears in the address script history
async fn verify_tx(
&self,
Expand Down Expand Up @@ -173,7 +179,7 @@ impl BitcoinChainService for HybridBitcoinChainService {
"Script history for {} got zero transactions, retrying in {} seconds...",
script_hash, retry
);
thread::sleep(Duration::from_secs(retry));
tokio::time::sleep(Duration::from_secs(retry)).await;
}
false => break,
}
Expand Down Expand Up @@ -214,6 +220,39 @@ impl BitcoinChainService for HybridBitcoinChainService {
Ok(self.client.batch_script_get_balance(scripts)?)
}

async fn script_get_balance_with_retry(
&self,
script: &Script,
retries: u64,
) -> Result<GetBalanceRes> {
let script_hash = sha256::Hash::hash(script.as_bytes()).to_hex();
info!("Fetching script balance for {}", script_hash);
let mut script_balance = GetBalanceRes {
confirmed: 0,
unconfirmed: 0,
};

let mut retry = 0;
while retry <= retries {
script_balance = self.script_get_balance(script)?;
match script_balance {
GetBalanceRes {
confirmed: 0,
unconfirmed: 0,
} => {
retry += 1;
info!(
"Got zero balance for script {}, retrying in {} seconds...",
script_hash, retry
);
tokio::time::sleep(Duration::from_secs(retry)).await;
}
_ => break,
}
}
Ok(script_balance)
}

async fn verify_tx(
&self,
address: &Address,
Expand Down
6 changes: 3 additions & 3 deletions lib/core/src/chain/liquid.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{str::FromStr, thread, time::Duration};
use std::{str::FromStr, time::Duration};

use anyhow::{anyhow, Result};
use async_trait::async_trait;
Expand Down Expand Up @@ -192,7 +192,7 @@ impl LiquidChainService for HybridLiquidChainService {
retry += 1;
info!("Script history for {script_hash} is empty, retrying in 1 second... ({retry} of {retries})");
// Waiting 1s between retries, so we detect the new tx as soon as possible
thread::sleep(Duration::from_secs(1));
tokio::time::sleep(Duration::from_secs(1)).await;
}
false => break,
}
Expand Down Expand Up @@ -290,7 +290,7 @@ async fn get_with_retry(url: &str, retries: usize) -> Result<Response> {
}
let secs = 1 << attempt;

thread::sleep(Duration::from_secs(secs));
tokio::time::sleep(Duration::from_secs(secs)).await;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/core/src/chain_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ impl ChainSwapHandler {
.bitcoin_chain_service
.lock()
.await
.script_get_balance(script_pubkey.as_script())?;
.script_get_balance_with_retry(script_pubkey.as_script(), 10)
.await?;
debug!("Found lockup balance {script_balance:?}");
let user_lockup_amount_sat = match script_balance.confirmed > 0 {
true => script_balance.confirmed,
Expand Down
8 changes: 8 additions & 0 deletions lib/core/src/test_utils/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ impl BitcoinChainService for MockBitcoinChainService {
unimplemented!()
}

async fn script_get_balance_with_retry(
&self,
_script: &boltz_client::bitcoin::Script,
_retries: u64,
) -> Result<electrum_client::GetBalanceRes> {
unimplemented!()
}

async fn verify_tx(
&self,
_address: &boltz_client::Address,
Expand Down

0 comments on commit e3fa3d6

Please sign in to comment.