@@ -668,31 +668,6 @@ where
668668 }
669669 }
670670
671- /// Returns an unsigned transaction spending an anchor output of the commitment transaction, and
672- /// any additional UTXOs sourced, to bump the commitment transaction's fee.
673- fn build_anchor_tx (
674- & self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
675- commitment_tx : & Transaction , anchor_descriptor : & AnchorDescriptor ,
676- ) -> Result < Transaction , ( ) > {
677- let must_spend = vec ! [ Input {
678- outpoint: anchor_descriptor. outpoint,
679- previous_utxo: anchor_descriptor. previous_utxo( ) ,
680- satisfaction_weight: commitment_tx. weight( ) as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ,
681- } ] ;
682- let coin_selection = self . utxo_source . select_confirmed_utxos (
683- claim_id, & must_spend, & [ ] , target_feerate_sat_per_1000_weight,
684- ) ?;
685-
686- let mut tx = Transaction {
687- version : 2 ,
688- lock_time : PackedLockTime :: ZERO , // TODO: Use next best height.
689- input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
690- output : vec ! [ ] ,
691- } ;
692- self . process_coin_selection ( & mut tx, coin_selection) ;
693- Ok ( tx)
694- }
695-
696671 /// Handles a [`BumpTransactionEvent::ChannelClose`] event variant by producing a fully-signed
697672 /// transaction spending an anchor output of the commitment transaction to bump its fee and
698673 /// broadcasts them to the network as a package.
@@ -713,27 +688,55 @@ where
713688 FEERATE_FLOOR_SATS_PER_KW ,
714689 ) ;
715690
716- let mut anchor_tx = self . build_anchor_tx (
717- claim_id, anchor_target_feerate_sat_per_1000_weight, commitment_tx, anchor_descriptor,
691+ let must_spend = vec ! [ Input {
692+ outpoint: anchor_descriptor. outpoint,
693+ previous_utxo: anchor_descriptor. previous_utxo( ) ,
694+ satisfaction_weight: commitment_tx. weight( ) as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ,
695+ } ] ;
696+ let coin_selection = self . utxo_source . select_confirmed_utxos (
697+ claim_id, & must_spend, & [ ] , anchor_target_feerate_sat_per_1000_weight,
718698 ) ?;
699+
700+ let mut anchor_tx = Transaction {
701+ version : 2 ,
702+ lock_time : PackedLockTime :: ZERO , // TODO: Use next best height.
703+ input : vec ! [ anchor_descriptor. unsigned_tx_input( ) ] ,
704+ output : vec ! [ ] ,
705+ } ;
706+ #[ cfg( debug_assertions) ]
707+ let total_satisfaction_weight =
708+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) +
709+ ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT ;
710+
711+ self . process_coin_selection ( & mut anchor_tx, coin_selection) ;
712+
719713 debug_assert_eq ! ( anchor_tx. output. len( ) , 1 ) ;
714+ #[ cfg( debug_assertions) ]
715+ let unsigned_tx_weight = anchor_tx. weight ( ) as u64 - ( anchor_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
720716
721717 self . utxo_source . sign_tx ( & mut anchor_tx) ?;
722718 let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
723719 let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
724720 anchor_tx. input [ 0 ] . witness = anchor_descriptor. tx_input_witness ( & anchor_sig) ;
725721
722+ #[ cfg( debug_assertions) ] {
723+ let signed_tx_weight = anchor_tx. weight ( ) as u64 ;
724+ 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) ;
727+ }
728+
726729 self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
727730 Ok ( ( ) )
728731 }
729732
730- /// Returns an unsigned, fee-bumped HTLC transaction, along with the set of signers required to
731- /// fulfill the witness for each HTLC input within it .
732- fn build_htlc_tx (
733+ /// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
734+ /// fully-signed, fee-bumped HTLC transaction that is broadcast to the network .
735+ fn handle_htlc_resolution (
733736 & self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
734737 htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : PackedLockTime ,
735- ) -> Result < Transaction , ( ) > {
736- let mut tx = Transaction {
738+ ) -> Result < ( ) , ( ) > {
739+ let mut htlc_tx = Transaction {
737740 version : 2 ,
738741 lock_time : tx_lock_time,
739742 input : vec ! [ ] ,
@@ -751,27 +754,22 @@ where
751754 HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT
752755 } ,
753756 } ) ;
754- tx . input . push ( htlc_input) ;
757+ htlc_tx . input . push ( htlc_input) ;
755758 let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
756- tx . output . push ( htlc_output) ;
759+ htlc_tx . output . push ( htlc_output) ;
757760 }
758761
759762 let coin_selection = self . utxo_source . select_confirmed_utxos (
760- claim_id, & must_spend, & tx . output , target_feerate_sat_per_1000_weight,
763+ claim_id, & must_spend, & htlc_tx . output , target_feerate_sat_per_1000_weight,
761764 ) ?;
762- self . process_coin_selection ( & mut tx, coin_selection) ;
763- Ok ( tx)
764- }
765+ #[ cfg( debug_assertions) ]
766+ let total_satisfaction_weight =
767+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum :: < u64 > ( ) +
768+ must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum :: < u64 > ( ) ;
769+ self . process_coin_selection ( & mut htlc_tx, coin_selection) ;
765770
766- /// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
767- /// fully-signed, fee-bumped HTLC transaction that is broadcast to the network.
768- fn handle_htlc_resolution (
769- & self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
770- htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : PackedLockTime ,
771- ) -> Result < ( ) , ( ) > {
772- let mut htlc_tx = self . build_htlc_tx (
773- claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time,
774- ) ?;
771+ #[ cfg( debug_assertions) ]
772+ let unsigned_tx_weight = htlc_tx. weight ( ) as u64 - ( htlc_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
775773
776774 self . utxo_source . sign_tx ( & mut htlc_tx) ?;
777775 let mut signers = BTreeMap :: new ( ) ;
@@ -783,6 +781,13 @@ where
783781 htlc_tx. input [ idx] . witness = htlc_descriptor. tx_input_witness ( & htlc_sig, & witness_script) ;
784782 }
785783
784+ #[ cfg( debug_assertions) ] {
785+ let signed_tx_weight = htlc_tx. weight ( ) as u64 ;
786+ 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) ;
789+ }
790+
786791 self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
787792 Ok ( ( ) )
788793 }
@@ -792,7 +797,7 @@ where
792797 match event {
793798 BumpTransactionEvent :: ChannelClose {
794799 claim_id, package_target_feerate_sat_per_1000_weight, commitment_tx,
795- anchor_descriptor , commitment_tx_fee_satoshis , ..
800+ commitment_tx_fee_satoshis , anchor_descriptor , ..
796801 } => {
797802 if let Err ( _) = self . handle_channel_close (
798803 * claim_id, * package_target_feerate_sat_per_1000_weight, commitment_tx,
0 commit comments