@@ -140,6 +140,15 @@ pub struct HTLCDescriptor {
140140}
141141
142142impl HTLCDescriptor {
143+ /// Returns the outpoint of the HTLC output in the commitment transaction. This is the outpoint
144+ /// being spent by the HTLC input in the HTLC transaction.
145+ pub fn outpoint ( & self ) -> OutPoint {
146+ OutPoint {
147+ txid : self . commitment_txid ,
148+ vout : self . htlc . transaction_output_index . unwrap ( ) ,
149+ }
150+ }
151+
143152 /// Returns the UTXO to be spent by the HTLC input, which can be obtained via
144153 /// [`Self::unsigned_tx_input`].
145154 pub fn previous_utxo < C : secp256k1:: Signing + secp256k1:: Verification > ( & self , secp : & Secp256k1 < C > ) -> TxOut {
@@ -480,19 +489,28 @@ pub trait WalletSource {
480489/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
481490/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
482491/// spends may happen.
483- pub struct Wallet < W : Deref > where W :: Target : WalletSource {
492+ pub struct Wallet < W : Deref , L : Deref >
493+ where
494+ W :: Target : WalletSource ,
495+ L :: Target : Logger
496+ {
484497 source : W ,
498+ logger : L ,
485499 // TODO: Do we care about cleaning this up once the UTXOs have a confirmed spend? We can do so
486500 // by checking whether any UTXOs that exist in the map are no longer returned in
487501 // `list_confirmed_utxos`.
488502 locked_utxos : Mutex < HashMap < OutPoint , ClaimId > > ,
489503}
490504
491- impl < W : Deref > Wallet < W > where W :: Target : WalletSource {
505+ impl < W : Deref , L : Deref > Wallet < W , L >
506+ where
507+ W :: Target : WalletSource ,
508+ L :: Target : Logger
509+ {
492510 /// Returns a new instance backed by the given [`WalletSource`] that serves as an implementation
493511 /// of [`CoinSelectionSource`].
494- pub fn new ( source : W ) -> Self {
495- Self { source, locked_utxos : Mutex :: new ( HashMap :: new ( ) ) }
512+ pub fn new ( source : W , logger : L ) -> Self {
513+ Self { source, logger , locked_utxos : Mutex :: new ( HashMap :: new ( ) ) }
496514 }
497515
498516 /// Performs coin selection on the set of UTXOs obtained from
@@ -512,6 +530,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
512530 let mut eligible_utxos = utxos. iter ( ) . filter_map ( |utxo| {
513531 if let Some ( utxo_claim_id) = locked_utxos. get ( & utxo. outpoint ) {
514532 if * utxo_claim_id != claim_id && !force_conflicting_utxo_spend {
533+ log_debug ! ( self . logger, "Skipping UTXO {} to prevent conflicting spend" , utxo. outpoint) ;
515534 return None ;
516535 }
517536 }
@@ -526,6 +545,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
526545 if should_spend {
527546 Some ( ( utxo, fee_to_spend_utxo) )
528547 } else {
548+ log_debug ! ( self . logger, "Skipping UTXO {} due to dust proximity after spend" , utxo. outpoint) ;
529549 None
530550 }
531551 } ) . collect :: < Vec < _ > > ( ) ;
@@ -543,6 +563,8 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
543563 selected_utxos. push ( utxo. clone ( ) ) ;
544564 }
545565 if selected_amount < target_amount_sat + total_fees {
566+ log_debug ! ( self . logger, "Insufficient funds to meet target feerate {} sat/kW" ,
567+ target_feerate_sat_per_1000_weight) ;
546568 return Err ( ( ) ) ;
547569 }
548570 for utxo in & selected_utxos {
@@ -559,6 +581,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
559581 ) ;
560582 let change_output_amount = remaining_amount. saturating_sub ( change_output_fee) ;
561583 let change_output = if change_output_amount < change_script. dust_value ( ) . to_sat ( ) {
584+ log_debug ! ( self . logger, "Coin selection attempt did not yield change output" ) ;
562585 None
563586 } else {
564587 Some ( TxOut { script_pubkey : change_script, value : change_output_amount } )
@@ -571,7 +594,11 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
571594 }
572595}
573596
574- impl < W : Deref > CoinSelectionSource for Wallet < W > where W :: Target : WalletSource {
597+ impl < W : Deref , L : Deref > CoinSelectionSource for Wallet < W , L >
598+ where
599+ W :: Target : WalletSource ,
600+ L :: Target : Logger
601+ {
575602 fn select_confirmed_utxos (
576603 & self , claim_id : ClaimId , must_spend : & [ Input ] , must_pay_to : & [ TxOut ] ,
577604 target_feerate_sat_per_1000_weight : u32 ,
@@ -589,6 +616,8 @@ impl<W: Deref> CoinSelectionSource for Wallet<W> where W::Target: WalletSource {
589616 ( ( BASE_TX_SIZE + total_output_size) * WITNESS_SCALE_FACTOR as u64 ) ;
590617 let target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ;
591618 let do_coin_selection = |force_conflicting_utxo_spend : bool , tolerate_high_network_feerates : bool | {
619+ log_debug ! ( self . logger, "Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})" ,
620+ target_feerate_sat_per_1000_weight, force_conflicting_utxo_spend, tolerate_high_network_feerates) ;
592621 self . select_confirmed_utxos_internal (
593622 & utxos, claim_id, force_conflicting_utxo_spend, tolerate_high_network_feerates,
594623 target_feerate_sat_per_1000_weight, preexisting_tx_weight, target_amount_sat,
@@ -661,6 +690,7 @@ where
661690 // match, but we still need to have at least one output in the transaction for it to be
662691 // considered standard. We choose to go with an empty OP_RETURN as it is the cheapest
663692 // way to include a dummy output.
693+ log_debug ! ( self . logger, "Including dummy OP_RETURN output since an output is needed and a change output was not provided" ) ;
664694 tx. output . push ( TxOut {
665695 value : 0 ,
666696 script_pubkey : Script :: new_op_return ( & [ ] ) ,
@@ -688,6 +718,8 @@ where
688718 FEERATE_FLOOR_SATS_PER_KW ,
689719 ) ;
690720
721+ log_debug ! ( self . logger, "Peforming coin selection for anchor transaction targeting {} sat/kW" ,
722+ anchor_target_feerate_sat_per_1000_weight) ;
691723 let must_spend = vec ! [ Input {
692724 outpoint: anchor_descriptor. outpoint,
693725 previous_utxo: anchor_descriptor. previous_utxo( ) ,
@@ -709,11 +741,13 @@ where
709741 ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ;
710742
711743 self . process_coin_selection ( & mut anchor_tx, coin_selection) ;
744+ let anchor_txid = anchor_tx. txid ( ) ;
712745
713746 debug_assert_eq ! ( anchor_tx. output. len( ) , 1 ) ;
714747 #[ cfg( debug_assertions) ]
715748 let unsigned_tx_weight = anchor_tx. weight ( ) as u64 - ( anchor_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
716749
750+ log_debug ! ( self . logger, "Signing anchor transaction {}" , anchor_txid) ;
717751 self . utxo_source . sign_tx ( & mut anchor_tx) ?;
718752 let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
719753 let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
@@ -722,10 +756,14 @@ where
722756 #[ cfg( debug_assertions) ] {
723757 let signed_tx_weight = anchor_tx. weight ( ) as u64 ;
724758 let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
725- // Our estimate should be within a 1% error margin of the actual weight.
726- assert ! ( expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
759+ // Our estimate should be within a 1% error margin of the actual weight and we should
760+ // never underestimate.
761+ assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
762+ expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
727763 }
728764
765+ log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
766+ anchor_txid, commitment_tx. txid( ) ) ;
729767 self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
730768 Ok ( ( ) )
731769 }
@@ -759,6 +797,8 @@ where
759797 htlc_tx. output . push ( htlc_output) ;
760798 }
761799
800+ log_debug ! ( self . logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW" ,
801+ target_feerate_sat_per_1000_weight) ;
762802 let coin_selection = self . utxo_source . select_confirmed_utxos (
763803 claim_id, & must_spend, & htlc_tx. output , target_feerate_sat_per_1000_weight,
764804 ) ?;
@@ -771,6 +811,7 @@ where
771811 #[ cfg( debug_assertions) ]
772812 let unsigned_tx_weight = htlc_tx. weight ( ) as u64 - ( htlc_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
773813
814+ log_debug ! ( self . logger, "Signing HTLC transaction {}" , htlc_tx. txid( ) ) ;
774815 self . utxo_source . sign_tx ( & mut htlc_tx) ?;
775816 let mut signers = BTreeMap :: new ( ) ;
776817 for ( idx, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
@@ -784,10 +825,13 @@ where
784825 #[ cfg( debug_assertions) ] {
785826 let signed_tx_weight = htlc_tx. weight ( ) as u64 ;
786827 let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
787- // Our estimate should be within a 1% error margin of the actual weight.
788- assert ! ( expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
828+ // Our estimate should be within a 1% error margin of the actual weight and we should
829+ // never underestimate.
830+ assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
831+ expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
789832 }
790833
834+ log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
791835 self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
792836 Ok ( ( ) )
793837 }
@@ -799,6 +843,8 @@ where
799843 claim_id, package_target_feerate_sat_per_1000_weight, commitment_tx,
800844 commitment_tx_fee_satoshis, anchor_descriptor, ..
801845 } => {
846+ log_info ! ( self . logger, "Handling channel close bump (claim_id = {}, commitment_txid = {})" ,
847+ log_bytes!( claim_id. 0 ) , commitment_tx. txid( ) ) ;
802848 if let Err ( _) = self . handle_channel_close (
803849 * claim_id, * package_target_feerate_sat_per_1000_weight, commitment_tx,
804850 * commitment_tx_fee_satoshis, anchor_descriptor,
@@ -810,6 +856,9 @@ where
810856 BumpTransactionEvent :: HTLCResolution {
811857 claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time,
812858 } => {
859+ log_info ! ( self . logger, "Handling HTLC bump (claim_id = {}, htlcs_to_claim = {:?})" ,
860+ log_bytes!( claim_id. 0 ) ,
861+ htlc_descriptors. iter( ) . map( |d| d. outpoint( ) . to_string( ) ) . collect:: <Vec <_>>( ) ) ;
813862 if let Err ( _) = self . handle_htlc_resolution (
814863 * claim_id, * target_feerate_sat_per_1000_weight, htlc_descriptors, * tx_lock_time,
815864 ) {
0 commit comments