@@ -140,6 +140,15 @@ pub struct HTLCDescriptor {
140
140
}
141
141
142
142
impl 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
+
143
152
/// Returns the UTXO to be spent by the HTLC input, which can be obtained via
144
153
/// [`Self::unsigned_tx_input`].
145
154
pub fn previous_utxo < C : secp256k1:: Signing + secp256k1:: Verification > ( & self , secp : & Secp256k1 < C > ) -> TxOut {
@@ -480,19 +489,28 @@ pub trait WalletSource {
480
489
/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
481
490
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
482
491
/// 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
+ {
484
497
source : W ,
498
+ logger : L ,
485
499
// TODO: Do we care about cleaning this up once the UTXOs have a confirmed spend? We can do so
486
500
// by checking whether any UTXOs that exist in the map are no longer returned in
487
501
// `list_confirmed_utxos`.
488
502
locked_utxos : Mutex < HashMap < OutPoint , ClaimId > > ,
489
503
}
490
504
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
+ {
492
510
/// Returns a new instance backed by the given [`WalletSource`] that serves as an implementation
493
511
/// 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 ( ) ) }
496
514
}
497
515
498
516
/// Performs coin selection on the set of UTXOs obtained from
@@ -512,6 +530,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
512
530
let mut eligible_utxos = utxos. iter ( ) . filter_map ( |utxo| {
513
531
if let Some ( utxo_claim_id) = locked_utxos. get ( & utxo. outpoint ) {
514
532
if * utxo_claim_id != claim_id && !force_conflicting_utxo_spend {
533
+ log_debug ! ( self . logger, "Skipping UTXO {} to prevent conflicting spend" , utxo. outpoint) ;
515
534
return None ;
516
535
}
517
536
}
@@ -526,6 +545,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
526
545
if should_spend {
527
546
Some ( ( utxo, fee_to_spend_utxo) )
528
547
} else {
548
+ log_debug ! ( self . logger, "Skipping UTXO {} due to dust proximity after spend" , utxo. outpoint) ;
529
549
None
530
550
}
531
551
} ) . collect :: < Vec < _ > > ( ) ;
@@ -543,6 +563,8 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
543
563
selected_utxos. push ( utxo. clone ( ) ) ;
544
564
}
545
565
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) ;
546
568
return Err ( ( ) ) ;
547
569
}
548
570
for utxo in & selected_utxos {
@@ -559,6 +581,7 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
559
581
) ;
560
582
let change_output_amount = remaining_amount. saturating_sub ( change_output_fee) ;
561
583
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" ) ;
562
585
None
563
586
} else {
564
587
Some ( TxOut { script_pubkey : change_script, value : change_output_amount } )
@@ -571,7 +594,11 @@ impl<W: Deref> Wallet<W> where W::Target: WalletSource {
571
594
}
572
595
}
573
596
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
+ {
575
602
fn select_confirmed_utxos (
576
603
& self , claim_id : ClaimId , must_spend : & [ Input ] , must_pay_to : & [ TxOut ] ,
577
604
target_feerate_sat_per_1000_weight : u32 ,
@@ -589,6 +616,8 @@ impl<W: Deref> CoinSelectionSource for Wallet<W> where W::Target: WalletSource {
589
616
( ( BASE_TX_SIZE + total_output_size) * WITNESS_SCALE_FACTOR as u64 ) ;
590
617
let target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ;
591
618
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) ;
592
621
self . select_confirmed_utxos_internal (
593
622
& utxos, claim_id, force_conflicting_utxo_spend, tolerate_high_network_feerates,
594
623
target_feerate_sat_per_1000_weight, preexisting_tx_weight, target_amount_sat,
@@ -661,6 +690,7 @@ where
661
690
// match, but we still need to have at least one output in the transaction for it to be
662
691
// considered standard. We choose to go with an empty OP_RETURN as it is the cheapest
663
692
// 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" ) ;
664
694
tx. output . push ( TxOut {
665
695
value : 0 ,
666
696
script_pubkey : Script :: new_op_return ( & [ ] ) ,
@@ -688,6 +718,8 @@ where
688
718
FEERATE_FLOOR_SATS_PER_KW ,
689
719
) ;
690
720
721
+ log_debug ! ( self . logger, "Peforming coin selection for anchor transaction targeting {} sat/kW" ,
722
+ anchor_target_feerate_sat_per_1000_weight) ;
691
723
let must_spend = vec ! [ Input {
692
724
outpoint: anchor_descriptor. outpoint,
693
725
previous_utxo: anchor_descriptor. previous_utxo( ) ,
@@ -709,11 +741,13 @@ where
709
741
ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ;
710
742
711
743
self . process_coin_selection ( & mut anchor_tx, coin_selection) ;
744
+ let anchor_txid = anchor_tx. txid ( ) ;
712
745
713
746
debug_assert_eq ! ( anchor_tx. output. len( ) , 1 ) ;
714
747
#[ cfg( debug_assertions) ]
715
748
let unsigned_tx_weight = anchor_tx. weight ( ) as u64 - ( anchor_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
716
749
750
+ log_debug ! ( self . logger, "Signing anchor transaction {}" , anchor_txid) ;
717
751
self . utxo_source . sign_tx ( & mut anchor_tx) ?;
718
752
let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
719
753
let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
@@ -722,10 +756,14 @@ where
722
756
#[ cfg( debug_assertions) ] {
723
757
let signed_tx_weight = anchor_tx. weight ( ) as u64 ;
724
758
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) ;
727
763
}
728
764
765
+ log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
766
+ anchor_txid, commitment_tx. txid( ) ) ;
729
767
self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
730
768
Ok ( ( ) )
731
769
}
@@ -759,6 +797,8 @@ where
759
797
htlc_tx. output . push ( htlc_output) ;
760
798
}
761
799
800
+ log_debug ! ( self . logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW" ,
801
+ target_feerate_sat_per_1000_weight) ;
762
802
let coin_selection = self . utxo_source . select_confirmed_utxos (
763
803
claim_id, & must_spend, & htlc_tx. output , target_feerate_sat_per_1000_weight,
764
804
) ?;
@@ -771,6 +811,7 @@ where
771
811
#[ cfg( debug_assertions) ]
772
812
let unsigned_tx_weight = htlc_tx. weight ( ) as u64 - ( htlc_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
773
813
814
+ log_debug ! ( self . logger, "Signing HTLC transaction {}" , htlc_tx. txid( ) ) ;
774
815
self . utxo_source . sign_tx ( & mut htlc_tx) ?;
775
816
let mut signers = BTreeMap :: new ( ) ;
776
817
for ( idx, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
@@ -784,10 +825,13 @@ where
784
825
#[ cfg( debug_assertions) ] {
785
826
let signed_tx_weight = htlc_tx. weight ( ) as u64 ;
786
827
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) ;
789
832
}
790
833
834
+ log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
791
835
self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
792
836
Ok ( ( ) )
793
837
}
@@ -799,6 +843,8 @@ where
799
843
claim_id, package_target_feerate_sat_per_1000_weight, commitment_tx,
800
844
commitment_tx_fee_satoshis, anchor_descriptor, ..
801
845
} => {
846
+ log_info ! ( self . logger, "Handling channel close bump (claim_id = {}, commitment_txid = {})" ,
847
+ log_bytes!( claim_id. 0 ) , commitment_tx. txid( ) ) ;
802
848
if let Err ( _) = self . handle_channel_close (
803
849
* claim_id, * package_target_feerate_sat_per_1000_weight, commitment_tx,
804
850
* commitment_tx_fee_satoshis, anchor_descriptor,
@@ -810,6 +856,9 @@ where
810
856
BumpTransactionEvent :: HTLCResolution {
811
857
claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time,
812
858
} => {
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 <_>>( ) ) ;
813
862
if let Err ( _) = self . handle_htlc_resolution (
814
863
* claim_id, * target_feerate_sat_per_1000_weight, htlc_descriptors, * tx_lock_time,
815
864
) {
0 commit comments