1use bitcoin::FeeRate;
2use log::warn;
3
4use crate::Wallet;
5use crate::exit::{Exit, ExitProgressStatus};
6use crate::onchain::{CpfpError, ExitUnilaterally, MakeCpfpFees};
7
8impl Exit {
9 pub async fn progress_exits_with_bdk(
23 &self,
24 wallet: &Wallet,
25 onchain: &mut dyn ExitUnilaterally,
26 fee_rate_override: Option<FeeRate>,
27 ) -> anyhow::Result<Option<Vec<ExitProgressStatus>>> {
28 self.progress_exits(wallet).await?;
29
30 let fee_rate = fee_rate_override.unwrap_or(wallet.chain().fee_rates().await.fast);
31 for req in self.exits_needing_cpfp().await {
32 let fees = match req.rbf_requirement {
33 None => MakeCpfpFees::Effective(fee_rate),
34 Some(rbf) => {
35 if fee_rate <= rbf.min_fee_rate {
38 warn!(
39 "Skipping exit CPFP RBF: requested fee rate {} is not above current package rate {}",
40 fee_rate, rbf.min_fee_rate,
41 );
42 continue;
43 }
44 MakeCpfpFees::Rbf {
45 min_effective_fee_rate: fee_rate,
46 current_package_fee: rbf.current_package_fee,
47 }
48 },
49 };
50 let child_tx = match onchain.make_signed_p2a_cpfp(&req.exit_tx, fees) {
51 Ok(tx) => tx,
52 Err(CpfpError::InsufficientConfirmedFunds { needed, available }) => {
53 warn!("Insufficient funds for exit CPFP: needed {} available {}", needed, available);
54 continue;
55 },
56 Err(e) => return Err(e.into()),
57 };
58 onchain.store_signed_p2a_cpfp(&child_tx).await?;
59 let exit_txid = req.exit_tx.compute_txid();
60 self.provide_cpfp_tx(wallet, exit_txid, child_tx).await?;
61 }
62
63 self.progress_exits(wallet).await
64 }
65}