@@ -408,7 +408,7 @@ fn mark_confirmed_emers(
408408 Ok ( ( ) )
409409}
410410
411- enum ToBeCpfped {
411+ pub enum ToBeCpfped {
412412 Spend ( SpendTransaction ) ,
413413 Unvault ( UnvaultTransaction ) ,
414414}
@@ -447,18 +447,17 @@ impl ToBeCpfped {
447447 }
448448}
449449
450- // CPFP a bunch of transactions, bumping their feerate by at least `target_feerate`.
451- // `target_feerate` is expressed in sat/kWU.
452- // All the transactions' feerate MUST be below `target_feerate`.
453- fn cpfp_package (
450+ /// CPFP a bunch of transactions, bumping their feerate by at least `target_feerate`.
451+ /// `target_feerate` is expressed in sat/kWU.
452+ /// All the transactions' feerate MUST be below `target_feerate`.
453+ pub fn cpfp_package (
454454 revaultd : & Arc < RwLock < RevaultD > > ,
455455 bitcoind : & BitcoinD ,
456456 to_be_cpfped : Vec < ToBeCpfped > ,
457457 target_feerate : u64 ,
458- ) -> Result < ( ) , BitcoindError > {
458+ ) -> Result < Vec < Txid > , BitcoindError > {
459459 let revaultd = revaultd. read ( ) . unwrap ( ) ;
460460 let cpfp_descriptor = & revaultd. cpfp_descriptor ;
461-
462461 // First of all, compute all the information we need from the to-be-cpfped transactions.
463462 let mut txids = HashSet :: with_capacity ( to_be_cpfped. len ( ) ) ;
464463 let mut package_weight = 0 ;
@@ -473,14 +472,13 @@ fn cpfp_package(
473472 Some ( txin) => txins. push ( txin) ,
474473 None => {
475474 log:: error!( "No CPFP txin for tx '{}'" , tx. txid( ) ) ;
476- return Ok ( ( ) ) ;
475+ return Ok ( txids . into_iter ( ) . collect ( ) ) ;
477476 }
478477 }
479478 }
480479 let tx_feerate = ( package_fees. as_sat ( ) * 1_000 / package_weight) as u64 ; // to sats/kWU
481480 assert ! ( tx_feerate < target_feerate) ;
482481 let added_feerate = target_feerate - tx_feerate;
483-
484482 // Then construct the child PSBT
485483 let confirmed_cpfp_utxos: Vec < _ > = bitcoind
486484 . list_unspent_cpfp ( ) ?
@@ -508,40 +506,43 @@ fn cpfp_package(
508506 Ok ( tx) => tx,
509507 Err ( TransactionCreationError :: InsufficientFunds ) => {
510508 // Well, we're poor.
511- log:: error!(
512- "We wanted to feebump transactions '{:?}', but we don't have enough funds!" ,
513- txids
514- ) ;
515- return Ok ( ( ) ) ;
509+ return Err ( BitcoindError :: RevaultTx (
510+ revault_tx:: Error :: TransactionCreation ( TransactionCreationError :: InsufficientFunds ) ,
511+ ) ) ;
516512 }
517513 Err ( e) => {
518- log:: error!( "Error while creating CPFP transaction: '{}'" , e) ;
519- return Ok ( ( ) ) ;
514+ return Err ( BitcoindError :: RevaultTx (
515+ revault_tx:: Error :: TransactionCreation ( e) ,
516+ ) ) ;
520517 }
521518 } ;
522-
523519 // Finally, sign and (try to) broadcast the CPFP transaction
524520 let ( complete, psbt_signed) = bitcoind. sign_psbt ( psbt. psbt ( ) ) ?;
525521 if !complete {
526- log:: error!(
527- "Bitcoind returned a non-finalized CPFP PSBT: {}" ,
528- base64:: encode( encode:: serialize( & psbt_signed) )
529- ) ;
530- return Ok ( ( ) ) ;
522+ return Err ( BitcoindError :: Custom (
523+ format ! (
524+ "Bitcoind returned a non-finalized CPFP PSBT: {}" ,
525+ base64:: encode( encode:: serialize( & psbt_signed) )
526+ )
527+ . to_string ( ) ,
528+ ) ) ;
531529 }
532-
533530 let final_tx = psbt_signed. extract_tx ( ) ;
534531 if let Err ( e) = bitcoind. broadcast_transaction ( & final_tx) {
535- log :: error! ( "Error broadcasting '{:?}' CPFP tx: {}" , txids , e ) ;
536- } else {
537- log :: info! ( "CPFPed transactions with ids '{:?}'" , txids ) ;
532+ return Err ( BitcoindError :: Custom (
533+ format ! ( "Error broadcasting '{:?}' CPFP tx: {}" , txids , e ) . to_string ( ) ,
534+ ) ) ;
538535 }
539-
540- Ok ( ( ) )
536+ log :: info! ( "CPFPed transactions with ids '{:?}'" , txids ) ;
537+ Ok ( txids . into_iter ( ) . collect ( ) )
541538}
542539
543- // `target_feerate` is in sats/kWU
544- fn should_cpfp ( bitcoind : & BitcoinD , tx : & impl CpfpableTransaction , target_feerate : u64 ) -> bool {
540+ /// `target_feerate` is in sats/kWU
541+ pub fn should_cpfp (
542+ bitcoind : & BitcoinD ,
543+ tx : & impl CpfpableTransaction ,
544+ target_feerate : u64 ,
545+ ) -> bool {
545546 bitcoind
546547 . get_wallet_transaction ( & tx. txid ( ) )
547548 // In the unlikely (actually, shouldn't happen but hey) case where
@@ -599,7 +600,14 @@ fn maybe_cpfp_txs(
599600 // TODO: std transaction max size check and split
600601 // TODO: smarter RBF (especially opportunistically with the fee delta)
601602 if !to_cpfp. is_empty ( ) {
602- cpfp_package ( revaultd, bitcoind, to_cpfp, current_feerate) ?;
603+ match cpfp_package ( revaultd, bitcoind, to_cpfp, current_feerate) {
604+ Err ( e) => {
605+ log:: error!( "Error broadcasting CPFP: {}" , e) ;
606+ }
607+ Ok ( txids) => {
608+ log:: info!( "CPFPed transactions with ids '{:?}'" , txids) ;
609+ }
610+ }
603611 } else {
604612 log:: debug!( "Nothing to CPFP" ) ;
605613 }
0 commit comments