@@ -3,9 +3,17 @@ pub mod poller;
33pub mod utils;
44
55use crate :: config:: BitcoindConfig ;
6- use crate :: { database:: DatabaseError , revaultd:: RevaultD , threadmessages:: BitcoindMessageOut } ;
6+ use crate :: {
7+ commands:: CommandError ,
8+ database:: {
9+ interface:: { db_spend_transaction, db_unvault_transaction_by_txid} ,
10+ DatabaseError ,
11+ } ,
12+ revaultd:: RevaultD ,
13+ threadmessages:: BitcoindMessageOut ,
14+ } ;
715use interface:: { BitcoinD , WalletTransaction } ;
8- use poller:: poller_main;
16+ use poller:: { cpfp_package , poller_main, should_cpfp , ToBeCpfped } ;
917use revault_tx:: bitcoin:: { Network , Txid } ;
1018
1119use std:: {
@@ -187,6 +195,61 @@ fn wallet_transaction(bitcoind: &BitcoinD, txid: Txid) -> Option<WalletTransacti
187195 . ok ( )
188196}
189197
198+ fn cpfp (
199+ revaultd : Arc < RwLock < RevaultD > > ,
200+ bitcoind : Arc < RwLock < BitcoinD > > ,
201+ txids : Vec < Txid > ,
202+ feerate : f64 ,
203+ ) -> Result < Vec < Txid > , CommandError > {
204+ let db_path = revaultd. read ( ) . unwrap ( ) . db_file ( ) ;
205+ assert ! ( revaultd. read( ) . unwrap( ) . is_manager( ) ) ;
206+
207+ let mut cpfp_txs = Vec :: with_capacity ( txids. len ( ) ) ;
208+ let mut cpfp_txids = Vec :: with_capacity ( txids. len ( ) ) ;
209+
210+ // sats/vbyte -> sats/WU
211+ let sats_wu = feerate / 4.0 ;
212+
213+ // sats/WU -> sats/kWU
214+ let sats_kwu = ( sats_wu * 1000.0 ) as u64 ;
215+
216+ for txid in txids. iter ( ) {
217+ let spend_tx = db_spend_transaction ( & db_path, & txid) . expect ( "Database must be available" ) ;
218+
219+ if let Some ( unwrap_spend_tx) = spend_tx {
220+ // If the transaction is of type SpendTransaction
221+ let psbt = unwrap_spend_tx. psbt ;
222+ if should_cpfp ( & bitcoind. read ( ) . unwrap ( ) , & psbt, sats_kwu) {
223+ cpfp_txs. push ( ToBeCpfped :: Spend ( psbt) ) ;
224+ cpfp_txids. push ( txid. clone ( ) ) ;
225+ }
226+ } else {
227+ let unvault_tx = match db_unvault_transaction_by_txid ( & db_path, & txid)
228+ . expect ( "Database must be available" )
229+ {
230+ Some ( tx) => tx,
231+ None => return Err ( CommandError :: InvalidParams ( "Unknown Txid." . to_string ( ) ) ) ,
232+ } ;
233+ // The transaction type is asserted to be UnvaultTransaction
234+ let psbt = unvault_tx. psbt . assert_unvault ( ) ;
235+ if should_cpfp ( & bitcoind. read ( ) . unwrap ( ) , & psbt, sats_kwu) {
236+ cpfp_txs. push ( ToBeCpfped :: Unvault ( psbt) ) ;
237+ cpfp_txids. push ( txid. clone ( ) ) ;
238+ }
239+ }
240+ }
241+
242+ if cpfp_txids. len ( ) > 0 {
243+ match cpfp_package ( & revaultd, & bitcoind. read ( ) . unwrap ( ) , cpfp_txs, sats_kwu) {
244+ Err ( err) => return Err ( CommandError :: Bitcoind ( err) ) ,
245+ _ => { }
246+ }
247+ } else {
248+ log:: info!( "Nothing to CPFP in the given list." ) ;
249+ }
250+ Ok ( cpfp_txids)
251+ }
252+
190253/// The bitcoind event loop.
191254/// Listens for bitcoind requests (wallet / chain) and poll bitcoind every 30 seconds,
192255/// updating our state accordingly.
@@ -208,7 +271,8 @@ pub fn bitcoind_main_loop(
208271 let _bitcoind = bitcoind. clone ( ) ;
209272 let _sync_progress = sync_progress. clone ( ) ;
210273 let _shutdown = shutdown. clone ( ) ;
211- move || poller_main ( revaultd, _bitcoind, _sync_progress, _shutdown)
274+ let _revaultd = revaultd. clone ( ) ;
275+ move || poller_main ( _revaultd, _bitcoind, _sync_progress, _shutdown)
212276 } ) ;
213277
214278 for msg in rx {
@@ -252,6 +316,23 @@ pub fn bitcoind_main_loop(
252316 ) )
253317 } ) ?;
254318 }
319+ BitcoindMessageOut :: CPFPTransaction ( txids, feerate, resp_tx) => {
320+ log:: trace!( "Received 'cpfptransaction' from main thread" ) ;
321+
322+ let _bitcoind = bitcoind. clone ( ) ;
323+ let _revaultd = revaultd. clone ( ) ;
324+ resp_tx
325+ . send (
326+ cpfp ( _revaultd, _bitcoind, txids, feerate)
327+ . map ( |_v| { } )
328+ . map_err ( |e| {
329+ BitcoindError :: Custom ( format ! ( "Error CPFPing transactions: {}" , e) )
330+ } ) ,
331+ )
332+ . map_err ( |e| {
333+ BitcoindError :: Custom ( format ! ( "Sending transaction for CPFP: {}" , e) )
334+ } ) ?;
335+ }
255336 }
256337 }
257338
0 commit comments