@@ -3,9 +3,16 @@ pub mod poller;
33pub mod utils;
44
55use crate :: config:: BitcoindConfig ;
6- use crate :: { database:: DatabaseError , revaultd:: RevaultD , threadmessages:: BitcoindMessageOut } ;
6+ use crate :: {
7+ database:: {
8+ interface:: { db_spend_transaction, db_vault_by_unvault_txid} ,
9+ DatabaseError ,
10+ } ,
11+ revaultd:: RevaultD ,
12+ threadmessages:: BitcoindMessageOut ,
13+ } ;
714use interface:: { BitcoinD , WalletTransaction } ;
8- use poller:: poller_main;
15+ use poller:: { cpfp_package , poller_main, should_cpfp , ToBeCpfped } ;
916use revault_tx:: bitcoin:: { Network , Txid } ;
1017
1118use std:: {
@@ -187,6 +194,60 @@ fn wallet_transaction(bitcoind: &BitcoinD, txid: Txid) -> Option<WalletTransacti
187194 . ok ( )
188195}
189196
197+ fn cpfp (
198+ revaultd : Arc < RwLock < RevaultD > > ,
199+ bitcoind : Arc < RwLock < BitcoinD > > ,
200+ txids : Vec < Txid > ,
201+ feerate : f64 ,
202+ ) -> Result < ( ) , BitcoindError > {
203+ let db_path = revaultd. read ( ) . unwrap ( ) . db_file ( ) ;
204+ assert ! ( revaultd. read( ) . unwrap( ) . is_manager( ) ) ;
205+
206+ let mut cpfp_txs = Vec :: with_capacity ( txids. len ( ) ) ;
207+ let mut counter = 0 ;
208+ //
209+ // sats/vbyte -> sats/WU
210+ let sats_wu = feerate / 4.0 ;
211+ // sats/WU -> msats/WU
212+ let msats_wu = ( sats_wu * 1000.0 ) as u64 ;
213+
214+ // sats/WU -> sats/kWU
215+ let sats_kwu = ( sats_wu * 1000.0 ) as u64 ;
216+
217+ for txid in txids. iter ( ) {
218+ let spend_tx = db_spend_transaction ( & db_path, & txid) . expect ( "Database must be available" ) ;
219+
220+ if let Some ( unwrap_spend_tx) = spend_tx {
221+ // If the transaction is of type SpendTransaction
222+ let psbt = unwrap_spend_tx. psbt ;
223+ if should_cpfp ( & bitcoind. read ( ) . unwrap ( ) , & psbt, sats_kwu) {
224+ cpfp_txs. push ( ToBeCpfped :: Spend ( psbt) ) ;
225+ counter += 1 ;
226+ }
227+ } else {
228+ let unvault_pair =
229+ db_vault_by_unvault_txid ( & db_path, & txid) . expect ( "Database must be available" ) ;
230+ let unvault_tx = match unvault_pair {
231+ Some ( ( _vault, tx) ) => tx,
232+ None => return Err ( BitcoindError :: Custom ( "Unknown Txid." . to_string ( ) ) ) ,
233+ } ;
234+ // The transaction type is asserted to be UnvaultTransaction
235+ let psbt = unvault_tx. psbt . assert_unvault ( ) ;
236+ if should_cpfp ( & bitcoind. read ( ) . unwrap ( ) , & psbt, sats_kwu) {
237+ cpfp_txs. push ( ToBeCpfped :: Unvault ( psbt) ) ;
238+ counter += 1 ;
239+ }
240+ }
241+ }
242+
243+ if counter != 0 {
244+ cpfp_package ( & revaultd, & bitcoind. read ( ) . unwrap ( ) , cpfp_txs, msats_wu)
245+ } else {
246+ log:: info!( "Nothing to CPFP in the given list." ) ;
247+ Ok ( ( ) )
248+ }
249+ }
250+
190251/// The bitcoind event loop.
191252/// Listens for bitcoind requests (wallet / chain) and poll bitcoind every 30 seconds,
192253/// updating our state accordingly.
@@ -208,7 +269,8 @@ pub fn bitcoind_main_loop(
208269 let _bitcoind = bitcoind. clone ( ) ;
209270 let _sync_progress = sync_progress. clone ( ) ;
210271 let _shutdown = shutdown. clone ( ) ;
211- move || poller_main ( revaultd, _bitcoind, _sync_progress, _shutdown)
272+ let _revaultd = revaultd. clone ( ) ;
273+ move || poller_main ( _revaultd, _bitcoind, _sync_progress, _shutdown)
212274 } ) ;
213275
214276 for msg in rx {
@@ -252,6 +314,16 @@ pub fn bitcoind_main_loop(
252314 ) )
253315 } ) ?;
254316 }
317+ BitcoindMessageOut :: CPFPTransaction ( txids, feerate, resp_tx) => {
318+ log:: trace!( "Received 'cpfptransaction' from main thread" ) ;
319+
320+ resp_tx
321+ . send ( cpfp ( revaultd, bitcoind, txids, feerate) )
322+ . map_err ( |e| {
323+ BitcoindError :: Custom ( format ! ( "Sending transaction for CPFP: {}" , e) )
324+ } ) ?;
325+ return Ok ( ( ) ) ;
326+ }
255327 }
256328 }
257329
0 commit comments