@@ -668,31 +668,6 @@ where
668
668
}
669
669
}
670
670
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
-
696
671
/// Handles a [`BumpTransactionEvent::ChannelClose`] event variant by producing a fully-signed
697
672
/// transaction spending an anchor output of the commitment transaction to bump its fee and
698
673
/// broadcasts them to the network as a package.
@@ -713,27 +688,55 @@ where
713
688
FEERATE_FLOOR_SATS_PER_KW ,
714
689
) ;
715
690
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,
718
698
) ?;
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
+
719
713
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 ) ;
720
716
721
717
self . utxo_source . sign_tx ( & mut anchor_tx) ?;
722
718
let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
723
719
let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
724
720
anchor_tx. input [ 0 ] . witness = anchor_descriptor. tx_input_witness ( & anchor_sig) ;
725
721
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
+
726
729
self . broadcaster . broadcast_transactions ( & [ & commitment_tx, & anchor_tx] ) ;
727
730
Ok ( ( ) )
728
731
}
729
732
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 (
733
736
& self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
734
737
htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : PackedLockTime ,
735
- ) -> Result < Transaction , ( ) > {
736
- let mut tx = Transaction {
738
+ ) -> Result < ( ) , ( ) > {
739
+ let mut htlc_tx = Transaction {
737
740
version : 2 ,
738
741
lock_time : tx_lock_time,
739
742
input : vec ! [ ] ,
@@ -751,27 +754,22 @@ where
751
754
HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT
752
755
} ,
753
756
} ) ;
754
- tx . input . push ( htlc_input) ;
757
+ htlc_tx . input . push ( htlc_input) ;
755
758
let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
756
- tx . output . push ( htlc_output) ;
759
+ htlc_tx . output . push ( htlc_output) ;
757
760
}
758
761
759
762
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,
761
764
) ?;
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) ;
765
770
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 ) ;
775
773
776
774
self . utxo_source . sign_tx ( & mut htlc_tx) ?;
777
775
let mut signers = BTreeMap :: new ( ) ;
@@ -783,6 +781,13 @@ where
783
781
htlc_tx. input [ idx] . witness = htlc_descriptor. tx_input_witness ( & htlc_sig, & witness_script) ;
784
782
}
785
783
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
+
786
791
self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
787
792
Ok ( ( ) )
788
793
}
@@ -792,7 +797,7 @@ where
792
797
match event {
793
798
BumpTransactionEvent :: ChannelClose {
794
799
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 , ..
796
801
} => {
797
802
if let Err ( _) = self . handle_channel_close (
798
803
* claim_id, * package_target_feerate_sat_per_1000_weight, commitment_tx,
0 commit comments