Skip to content

Commit

Permalink
rescan_onchain_swaps: separate internal (scheduled) from external (ma…
Browse files Browse the repository at this point in the history
…nual) call
  • Loading branch information
ok300 committed Sep 13, 2024
1 parent 3897790 commit ecca6a1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
23 changes: 19 additions & 4 deletions lib/core/src/chain_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl ChainSwapHandler {
loop {
tokio::select! {
_ = rescan_interval.tick() => {
if let Err(e) = cloned.rescan_incoming_chain_swaps().await {
if let Err(e) = cloned.rescan_incoming_chain_swaps(false).await {
error!("Error checking incoming chain swaps: {e:?}");
}
if let Err(e) = cloned.rescan_outgoing_chain_swaps().await {
Expand Down Expand Up @@ -107,7 +107,10 @@ impl ChainSwapHandler {
}
}

pub(crate) async fn rescan_incoming_chain_swaps(&self) -> Result<()> {
pub(crate) async fn rescan_incoming_chain_swaps(
&self,
ignore_monitoring_block_height: bool,
) -> Result<()> {
let current_height = self.bitcoin_chain_service.lock().await.tip()?.height as u32;
let chain_swaps: Vec<ChainSwap> = self
.persister
Expand All @@ -121,22 +124,34 @@ impl ChainSwapHandler {
current_height
);
for swap in chain_swaps {
if let Err(e) = self.rescan_incoming_chain_swap(&swap, current_height).await {
if let Err(e) = self
.rescan_incoming_chain_swap(&swap, current_height, ignore_monitoring_block_height)
.await
{
error!("Error rescanning incoming Chain Swap {}: {e:?}", swap.id);
}
}
Ok(())
}

/// ### Arguments
/// - `swap`: the swap being rescanned
/// - `current_height`: the tip
/// - `ignore_monitoring_block_height`: if true, it rescans an expired swap even after the
/// cutoff monitoring block height
async fn rescan_incoming_chain_swap(
&self,
swap: &ChainSwap,
current_height: u32,
ignore_monitoring_block_height: bool,
) -> Result<()> {
let monitoring_block_height =
swap.timeout_block_height + CHAIN_SWAP_MONITORING_PERIOD_BITCOIN_BLOCKS;
let is_swap_expired = current_height > swap.timeout_block_height;
let is_monitoring_expired = current_height > monitoring_block_height;
let is_monitoring_expired = match ignore_monitoring_block_height {
true => false,
false => current_height > monitoring_block_height,
};

if (is_swap_expired && !is_monitoring_expired) || swap.state == RefundPending {
let swap_script = swap.get_lockup_swap_script()?.as_bitcoin_script()?;
Expand Down
11 changes: 8 additions & 3 deletions lib/core/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1815,11 +1815,16 @@ impl LiquidSdk {
Ok(RefundResponse { refund_tx_id })
}

/// Rescans all expired chain swaps created from calling [LiquidSdk::receive_onchain] within
/// the monitoring period to check if there are any confirmed funds available to refund.
/// Rescans all expired chain swaps created from calling [LiquidSdk::receive_onchain] to check
/// if there are any confirmed funds available to refund.
///
/// Since it bypasses the monitoring period, this should be called rarely or when the caller
/// expects there is a very old refundable chain swap. Otherwise, for relatively recent swaps
/// (within last [CHAIN_SWAP_MONITORING_PERIOD_BITCOIN_BLOCKS] blocks = ~30 days), calling this
/// is not necessary as it happens automatically in the background.
pub async fn rescan_onchain_swaps(&self) -> SdkResult<()> {
self.chain_swap_handler
.rescan_incoming_chain_swaps()
.rescan_incoming_chain_swaps(true)
.await?;
Ok(())
}
Expand Down

0 comments on commit ecca6a1

Please sign in to comment.