1414use alloc:: collections:: BTreeMap ;
1515use core:: ops:: Deref ;
1616
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} ;
1818use crate :: chain:: ClaimId ;
1919use crate :: io_extras:: sink;
2020use crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI ;
@@ -542,7 +542,7 @@ where
542542 fn select_confirmed_utxos_internal (
543543 & self , utxos : & [ Utxo ] , claim_id : ClaimId , force_conflicting_utxo_spend : bool ,
544544 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 ,
546546 ) -> Result < CoinSelection , ( ) > {
547547 let mut locked_utxos = self . locked_utxos . lock ( ) . unwrap ( ) ;
548548 let mut eligible_utxos = utxos. iter ( ) . filter_map ( |utxo| {
@@ -569,7 +569,7 @@ where
569569 } ) . collect :: < Vec < _ > > ( ) ;
570570 eligible_utxos. sort_unstable_by_key ( |( utxo, _) | utxo. output . value ) ;
571571
572- let mut selected_amount = 0 ;
572+ let mut selected_amount = input_amount_sat ;
573573 let mut total_fees = fee_for_weight ( target_feerate_sat_per_1000_weight, preexisting_tx_weight) ;
574574 let mut selected_utxos = Vec :: new ( ) ;
575575 for ( utxo, fee_to_spend_utxo) in eligible_utxos {
@@ -632,13 +632,14 @@ where
632632
633633 let preexisting_tx_weight = 2 /* segwit marker & flag */ + total_input_weight +
634634 ( ( 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 ( ) ;
635636 let target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ;
636637 let do_coin_selection = |force_conflicting_utxo_spend : bool , tolerate_high_network_feerates : bool | {
637638 log_debug ! ( self . logger, "Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})" ,
638639 target_feerate_sat_per_1000_weight, force_conflicting_utxo_spend, tolerate_high_network_feerates) ;
639640 self . select_confirmed_utxos_internal (
640641 & 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,
642643 )
643644 } ;
644645 do_coin_selection ( false , false )
@@ -724,27 +725,22 @@ where
724725 commitment_tx : & Transaction , commitment_tx_fee_sat : u64 , anchor_descriptor : & AnchorDescriptor ,
725726 ) -> Result < ( ) , ( ) > {
726727 // 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;
741732 let must_spend = vec ! [ Input {
742733 outpoint: anchor_descriptor. outpoint,
743- previous_utxo: anchor_descriptor . previous_utxo ( ) ,
734+ previous_utxo: anchor_utxo ,
744735 satisfaction_weight: commitment_tx. weight( ) as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ,
745736 } ] ;
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) ;
746742 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 ,
748744 ) ?;
749745
750746 let mut anchor_tx = Transaction {
@@ -753,10 +749,13 @@ where
753749 input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
754750 output : vec ! [ ] ,
755751 } ;
752+
756753 #[ 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 > ( ) ;
760759
761760 self . process_coin_selection ( & mut anchor_tx, coin_selection) ;
762761 let anchor_txid = anchor_tx. txid ( ) ;
@@ -779,6 +778,16 @@ where
779778 // never underestimate.
780779 assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
781780 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) ;
782791 }
783792
784793 log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
@@ -818,16 +827,24 @@ where
818827
819828 log_debug ! ( self . logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW" ,
820829 target_feerate_sat_per_1000_weight) ;
830+
821831 #[ cfg( debug_assertions) ]
822832 let must_spend_satisfaction_weight =
823833 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+
824837 let coin_selection = self . utxo_source . select_confirmed_utxos (
825838 claim_id, must_spend, & htlc_tx. output , target_feerate_sat_per_1000_weight,
826839 ) ?;
840+
827841 #[ 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+
831848 self . process_coin_selection ( & mut htlc_tx, coin_selection) ;
832849
833850 #[ cfg( debug_assertions) ]
@@ -852,6 +869,15 @@ where
852869 // never underestimate.
853870 assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
854871 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) ;
855881 }
856882
857883 log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
0 commit comments