14
14
use alloc:: collections:: BTreeMap ;
15
15
use core:: ops:: Deref ;
16
16
17
- use crate :: chain:: chaininterface:: { BroadcasterInterface , compute_feerate_sat_per_1000_weight , fee_for_weight, FEERATE_FLOOR_SATS_PER_KW } ;
17
+ use crate :: chain:: chaininterface:: { BroadcasterInterface , fee_for_weight} ;
18
18
use crate :: chain:: ClaimId ;
19
19
use crate :: io_extras:: sink;
20
20
use crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI ;
@@ -542,7 +542,7 @@ where
542
542
fn select_confirmed_utxos_internal (
543
543
& self , utxos : & [ Utxo ] , claim_id : ClaimId , force_conflicting_utxo_spend : bool ,
544
544
tolerate_high_network_feerates : bool , target_feerate_sat_per_1000_weight : u32 ,
545
- preexisting_tx_weight : u64 , target_amount_sat : u64 ,
545
+ preexisting_tx_weight : u64 , input_amount_sat : u64 , target_amount_sat : u64 ,
546
546
) -> Result < CoinSelection , ( ) > {
547
547
let mut locked_utxos = self . locked_utxos . lock ( ) . unwrap ( ) ;
548
548
let mut eligible_utxos = utxos. iter ( ) . filter_map ( |utxo| {
@@ -569,7 +569,7 @@ where
569
569
} ) . collect :: < Vec < _ > > ( ) ;
570
570
eligible_utxos. sort_unstable_by_key ( |( utxo, _) | utxo. output . value ) ;
571
571
572
- let mut selected_amount = 0 ;
572
+ let mut selected_amount = input_amount_sat ;
573
573
let mut total_fees = fee_for_weight ( target_feerate_sat_per_1000_weight, preexisting_tx_weight) ;
574
574
let mut selected_utxos = Vec :: new ( ) ;
575
575
for ( utxo, fee_to_spend_utxo) in eligible_utxos {
@@ -632,13 +632,14 @@ where
632
632
633
633
let preexisting_tx_weight = 2 /* segwit marker & flag */ + total_input_weight +
634
634
( ( BASE_TX_SIZE + total_output_size) * WITNESS_SCALE_FACTOR as u64 ) ;
635
+ let input_amount_sat: u64 = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum ( ) ;
635
636
let target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ;
636
637
let do_coin_selection = |force_conflicting_utxo_spend : bool , tolerate_high_network_feerates : bool | {
637
638
log_debug ! ( self . logger, "Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})" ,
638
639
target_feerate_sat_per_1000_weight, force_conflicting_utxo_spend, tolerate_high_network_feerates) ;
639
640
self . select_confirmed_utxos_internal (
640
641
& utxos, claim_id, force_conflicting_utxo_spend, tolerate_high_network_feerates,
641
- target_feerate_sat_per_1000_weight, preexisting_tx_weight, target_amount_sat,
642
+ target_feerate_sat_per_1000_weight, preexisting_tx_weight, input_amount_sat , target_amount_sat,
642
643
)
643
644
} ;
644
645
do_coin_selection ( false , false )
@@ -724,27 +725,22 @@ where
724
725
commitment_tx : & Transaction , commitment_tx_fee_sat : u64 , anchor_descriptor : & AnchorDescriptor ,
725
726
) -> Result < ( ) , ( ) > {
726
727
// Our commitment transaction already has fees allocated to it, so we should take them into
727
- // account. We compute its feerate and subtract it from the package target, using the result
728
- // as the target feerate for our anchor transaction. Unfortunately, this results in users
729
- // overpaying by a small margin since we don't yet know the anchor transaction size, and
730
- // avoiding the small overpayment only makes our API even more complex.
731
- let commitment_tx_sat_per_1000_weight: u32 = compute_feerate_sat_per_1000_weight (
732
- commitment_tx_fee_sat, commitment_tx. weight ( ) as u64 ,
733
- ) ;
734
- let anchor_target_feerate_sat_per_1000_weight = core:: cmp:: max (
735
- package_target_feerate_sat_per_1000_weight - commitment_tx_sat_per_1000_weight,
736
- FEERATE_FLOOR_SATS_PER_KW ,
737
- ) ;
738
-
739
- log_debug ! ( self . logger, "Peforming coin selection for anchor transaction targeting {} sat/kW" ,
740
- anchor_target_feerate_sat_per_1000_weight) ;
728
+ // account. We do so by pretending the commitment tranasction's fee and weight are part of
729
+ // the anchor input.
730
+ let mut anchor_utxo = anchor_descriptor. previous_utxo ( ) ;
731
+ anchor_utxo. value += commitment_tx_fee_sat;
741
732
let must_spend = vec ! [ Input {
742
733
outpoint: anchor_descriptor. outpoint,
743
- previous_utxo: anchor_descriptor . previous_utxo ( ) ,
734
+ previous_utxo: anchor_utxo ,
744
735
satisfaction_weight: commitment_tx. weight( ) as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ,
745
736
} ] ;
737
+ #[ cfg( debug_assertions) ]
738
+ let must_spend_amount = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum :: < u64 > ( ) ;
739
+
740
+ log_debug ! ( self . logger, "Peforming coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW" ,
741
+ package_target_feerate_sat_per_1000_weight) ;
746
742
let coin_selection = self . utxo_source . select_confirmed_utxos (
747
- claim_id, must_spend, & [ ] , anchor_target_feerate_sat_per_1000_weight ,
743
+ claim_id, must_spend, & [ ] , package_target_feerate_sat_per_1000_weight ,
748
744
) ?;
749
745
750
746
let mut anchor_tx = Transaction {
@@ -753,10 +749,13 @@ where
753
749
input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
754
750
output : vec ! [ ] ,
755
751
} ;
752
+
756
753
#[ cfg( debug_assertions) ]
757
- let total_satisfaction_weight =
758
- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) +
759
- ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ;
754
+ let total_satisfaction_weight = ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT +
755
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) ;
756
+ #[ cfg( debug_assertions) ]
757
+ let total_input_amount = must_spend_amount +
758
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ;
760
759
761
760
self . process_coin_selection ( & mut anchor_tx, coin_selection) ;
762
761
let anchor_txid = anchor_tx. txid ( ) ;
@@ -779,6 +778,16 @@ where
779
778
// never underestimate.
780
779
assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
781
780
expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
781
+
782
+ let expected_package_fee = fee_for_weight ( package_target_feerate_sat_per_1000_weight,
783
+ signed_tx_weight + commitment_tx. weight ( ) as u64 ) ;
784
+ let package_fee = total_input_amount -
785
+ anchor_tx. output . iter ( ) . map ( |output| output. value ) . sum :: < u64 > ( ) ;
786
+ // Our fee should be within a 5% error margin of the expected fee based on the
787
+ // feerate and transaction weight and we should never pay less than required.
788
+ let fee_error_margin = expected_package_fee * 5 / 100 ;
789
+ assert ! ( package_fee >= expected_package_fee &&
790
+ package_fee - fee_error_margin <= expected_package_fee) ;
782
791
}
783
792
784
793
log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
@@ -818,16 +827,24 @@ where
818
827
819
828
log_debug ! ( self . logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW" ,
820
829
target_feerate_sat_per_1000_weight) ;
830
+
821
831
#[ cfg( debug_assertions) ]
822
832
let must_spend_satisfaction_weight =
823
833
must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum :: < u64 > ( ) ;
834
+ #[ cfg( debug_assertions) ]
835
+ let must_spend_amount = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum :: < u64 > ( ) ;
836
+
824
837
let coin_selection = self . utxo_source . select_confirmed_utxos (
825
838
claim_id, must_spend, & htlc_tx. output , target_feerate_sat_per_1000_weight,
826
839
) ?;
840
+
827
841
#[ cfg( debug_assertions) ]
828
- let total_satisfaction_weight =
829
- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) +
830
- must_spend_satisfaction_weight;
842
+ let total_satisfaction_weight = must_spend_satisfaction_weight +
843
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) ;
844
+ #[ cfg( debug_assertions) ]
845
+ let total_input_amount = must_spend_amount +
846
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ;
847
+
831
848
self . process_coin_selection ( & mut htlc_tx, coin_selection) ;
832
849
833
850
#[ cfg( debug_assertions) ]
@@ -852,6 +869,15 @@ where
852
869
// never underestimate.
853
870
assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
854
871
expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
872
+
873
+ let expected_signed_tx_fee = fee_for_weight ( target_feerate_sat_per_1000_weight, signed_tx_weight) ;
874
+ let signed_tx_fee = total_input_amount -
875
+ htlc_tx. output . iter ( ) . map ( |output| output. value ) . sum :: < u64 > ( ) ;
876
+ // Our fee should be within a 5% error margin of the expected fee based on the
877
+ // feerate and transaction weight and we should never pay less than required.
878
+ let fee_error_margin = expected_signed_tx_fee * 5 / 100 ;
879
+ assert ! ( signed_tx_fee >= expected_signed_tx_fee &&
880
+ signed_tx_fee - fee_error_margin <= expected_signed_tx_fee) ;
855
881
}
856
882
857
883
log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
0 commit comments