From ecca6a14f1c339ca9bd5b4147c3ee4e2e007c243 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:55:25 +0200 Subject: [PATCH] rescan_onchain_swaps: separate internal (scheduled) from external (manual) call --- lib/core/src/chain_swap.rs | 23 +++++++++++++++++++---- lib/core/src/sdk.rs | 11 ++++++++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/core/src/chain_swap.rs b/lib/core/src/chain_swap.rs index caa97f73e..143d06c6a 100644 --- a/lib/core/src/chain_swap.rs +++ b/lib/core/src/chain_swap.rs @@ -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 { @@ -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 = self .persister @@ -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()?; diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index 0451726cc..5a686c89a 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -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(()) }