@@ -617,85 +617,105 @@ where
617617 let mut anchor_utxo = anchor_descriptor. previous_utxo ( ) ;
618618 let commitment_tx_fee_sat = Amount :: from_sat ( commitment_tx_fee_sat) ;
619619 anchor_utxo. value += commitment_tx_fee_sat;
620- let must_spend = vec ! [ Input {
621- outpoint: anchor_descriptor. outpoint,
622- previous_utxo: anchor_utxo,
623- satisfaction_weight: commitment_tx. weight( ) . to_wu( ) + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ,
624- } ] ;
625- #[ cfg( debug_assertions) ]
626- let must_spend_amount = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum :: < Amount > ( ) ;
627-
628- log_debug ! ( self . logger, "Performing coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW" ,
629- package_target_feerate_sat_per_1000_weight) ;
630- let coin_selection: CoinSelection = self . utxo_source . select_confirmed_utxos (
631- claim_id, must_spend, & [ ] , package_target_feerate_sat_per_1000_weight,
632- ) ?;
633-
634- let mut anchor_tx = Transaction {
635- version : Version :: TWO ,
636- lock_time : LockTime :: ZERO , // TODO: Use next best height.
637- input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
638- output : vec ! [ ] ,
639- } ;
640-
641- #[ cfg( debug_assertions) ]
642- let total_satisfaction_weight = ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT +
643- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) ;
644- #[ cfg( debug_assertions) ]
645- let total_input_amount = must_spend_amount +
646- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum ( ) ;
647-
648- self . process_coin_selection ( & mut anchor_tx, & coin_selection) ;
649- let anchor_txid = anchor_tx. compute_txid ( ) ;
620+ let starting_package_and_fixed_input_satisfaction_weight =
621+ commitment_tx. weight ( ) . to_wu ( ) + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ;
622+ let mut package_and_fixed_input_satisfaction_weight =
623+ starting_package_and_fixed_input_satisfaction_weight;
624+
625+ loop {
626+ let must_spend = vec ! [ Input {
627+ outpoint: anchor_descriptor. outpoint,
628+ previous_utxo: anchor_utxo. clone( ) ,
629+ satisfaction_weight: package_and_fixed_input_satisfaction_weight,
630+ } ] ;
631+ #[ cfg( debug_assertions) ]
632+ let must_spend_amount = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum :: < Amount > ( ) ;
633+
634+ log_debug ! ( self . logger, "Performing coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW" ,
635+ package_target_feerate_sat_per_1000_weight) ;
636+ let coin_selection: CoinSelection = self . utxo_source . select_confirmed_utxos (
637+ claim_id, must_spend, & [ ] , package_target_feerate_sat_per_1000_weight,
638+ ) ?;
639+
640+ let mut anchor_tx = Transaction {
641+ version : Version :: TWO ,
642+ lock_time : LockTime :: ZERO , // TODO: Use next best height.
643+ input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
644+ output : vec ! [ ] ,
645+ } ;
650646
651- // construct psbt
652- let mut anchor_psbt = Psbt :: from_unsigned_tx ( anchor_tx) . unwrap ( ) ;
653- // add witness_utxo to anchor input
654- anchor_psbt. inputs [ 0 ] . witness_utxo = Some ( anchor_descriptor. previous_utxo ( ) ) ;
655- // add witness_utxo to remaining inputs
656- for ( idx, utxo) in coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( ) {
657- // add 1 to skip the anchor input
658- let index = idx + 1 ;
659- debug_assert_eq ! ( anchor_psbt. unsigned_tx. input[ index] . previous_output, utxo. outpoint) ;
660- if utxo. output . script_pubkey . is_witness_program ( ) {
661- anchor_psbt. inputs [ index] . witness_utxo = Some ( utxo. output ) ;
647+ let total_satisfaction_weight = ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT +
648+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) ;
649+ let total_input_amount = must_spend_amount +
650+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum ( ) ;
651+
652+ self . process_coin_selection ( & mut anchor_tx, & coin_selection) ;
653+ let anchor_txid = anchor_tx. compute_txid ( ) ;
654+
655+ // construct psbt
656+ let mut anchor_psbt = Psbt :: from_unsigned_tx ( anchor_tx) . unwrap ( ) ;
657+ // add witness_utxo to anchor input
658+ anchor_psbt. inputs [ 0 ] . witness_utxo = Some ( anchor_descriptor. previous_utxo ( ) ) ;
659+ // add witness_utxo to remaining inputs
660+ for ( idx, utxo) in coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( ) {
661+ // add 1 to skip the anchor input
662+ let index = idx + 1 ;
663+ debug_assert_eq ! ( anchor_psbt. unsigned_tx. input[ index] . previous_output, utxo. outpoint) ;
664+ if utxo. output . script_pubkey . is_witness_program ( ) {
665+ anchor_psbt. inputs [ index] . witness_utxo = Some ( utxo. output ) ;
666+ }
662667 }
663- }
664-
665- debug_assert_eq ! ( anchor_psbt. unsigned_tx. output. len( ) , 1 ) ;
666- #[ cfg( debug_assertions) ]
667- let unsigned_tx_weight = anchor_psbt. unsigned_tx . weight ( ) . to_wu ( ) - ( anchor_psbt. unsigned_tx . input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
668668
669- log_debug ! ( self . logger , "Signing anchor transaction {}" , anchor_txid ) ;
670- anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) ? ;
669+ debug_assert_eq ! ( anchor_psbt . unsigned_tx . output . len ( ) , 1 ) ;
670+ let unsigned_tx_weight = anchor_psbt . unsigned_tx . weight ( ) . to_wu ( ) - ( anchor_psbt. unsigned_tx . input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
671671
672- let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
673- let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
674- anchor_tx. input [ 0 ] . witness = anchor_descriptor. tx_input_witness ( & anchor_sig) ;
672+ let package_fee = total_input_amount -
673+ anchor_psbt. unsigned_tx . output . iter ( ) . map ( |output| output. value ) . sum ( ) ;
674+ let package_weight = unsigned_tx_weight + total_satisfaction_weight + commitment_tx. weight ( ) . to_wu ( ) ;
675+ if package_fee. to_sat ( ) * 1000 / package_weight < package_target_feerate_sat_per_1000_weight. into ( ) {
676+ // On the first iteration of the loop, we may undershoot the target feerate because
677+ // we had to add an OP_RETURN output in `process_coin_selection` which we didn't
678+ // select sufficient coins for. Here we detect that case and go around again
679+ // seeking additional weight.
680+ if package_and_fixed_input_satisfaction_weight == starting_package_and_fixed_input_satisfaction_weight {
681+ debug_assert ! ( anchor_psbt. unsigned_tx. output[ 0 ] . script_pubkey. is_op_return( ) ,
682+ "Coin selection failed to select sufficient coins for its change output" ) ;
683+ package_and_fixed_input_satisfaction_weight += anchor_psbt. unsigned_tx . output [ 0 ] . weight ( ) . to_wu ( ) ;
684+ continue ;
685+ } else {
686+ debug_assert ! ( false , "Coin selection failed to select sufficient coins" ) ;
687+ }
688+ }
675689
676- #[ cfg( debug_assertions) ] {
677- let signed_tx_weight = anchor_tx. weight ( ) . to_wu ( ) ;
678- let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
679- // Our estimate should be within a 1% error margin of the actual weight and we should
680- // never underestimate.
681- assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
682- expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
690+ log_debug ! ( self . logger, "Signing anchor transaction {}" , anchor_txid) ;
691+ anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) ?;
692+
693+ let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
694+ let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
695+ anchor_tx. input [ 0 ] . witness = anchor_descriptor. tx_input_witness ( & anchor_sig) ;
696+
697+ #[ cfg( debug_assertions) ] {
698+ let signed_tx_weight = anchor_tx. weight ( ) . to_wu ( ) ;
699+ let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
700+ // Our estimate should be within a 1% error margin of the actual weight and we should
701+ // never underestimate.
702+ assert ! ( expected_signed_tx_weight >= signed_tx_weight &&
703+ expected_signed_tx_weight - ( expected_signed_tx_weight / 100 ) <= signed_tx_weight) ;
704+
705+ let expected_package_fee = Amount :: from_sat ( fee_for_weight ( package_target_feerate_sat_per_1000_weight,
706+ signed_tx_weight + commitment_tx. weight ( ) . to_wu ( ) ) ) ;
707+ // Our fee should be within a 5% error margin of the expected fee based on the
708+ // feerate and transaction weight and we should never pay less than required.
709+ let fee_error_margin = expected_package_fee * 5 / 100 ;
710+ assert ! ( package_fee >= expected_package_fee &&
711+ package_fee - fee_error_margin <= expected_package_fee) ;
712+ }
683713
684- let expected_package_fee = Amount :: from_sat ( fee_for_weight ( package_target_feerate_sat_per_1000_weight,
685- signed_tx_weight + commitment_tx. weight ( ) . to_wu ( ) ) ) ;
686- let package_fee = total_input_amount -
687- anchor_tx. output . iter ( ) . map ( |output| output. value ) . sum ( ) ;
688- // Our fee should be within a 5% error margin of the expected fee based on the
689- // feerate and transaction weight and we should never pay less than required.
690- let fee_error_margin = expected_package_fee * 5 / 100 ;
691- assert ! ( package_fee >= expected_package_fee &&
692- package_fee - fee_error_margin <= expected_package_fee) ;
714+ log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
715+ anchor_txid, commitment_tx. compute_txid( ) ) ;
716+ self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
717+ return Ok ( ( ) ) ;
693718 }
694-
695- log_info ! ( self . logger, "Broadcasting anchor transaction {} to bump channel close with txid {}" ,
696- anchor_txid, commitment_tx. compute_txid( ) ) ;
697- self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
698- Ok ( ( ) )
699719 }
700720
701721 /// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
0 commit comments