@@ -849,8 +849,8 @@ where
849
849
/// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
850
850
/// fully-signed, fee-bumped HTLC transaction that is broadcast to the network.
851
851
async fn handle_htlc_resolution (
852
- & self , target_feerate_sat_per_1000_weight : u32 , htlc_descriptors : & [ HTLCDescriptor ] ,
853
- tx_lock_time : LockTime ,
852
+ & self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
853
+ htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : LockTime ,
854
854
) -> Result < ( ) , ( ) > {
855
855
let channel_type = & htlc_descriptors[ 0 ]
856
856
. channel_derivation_parameters
@@ -885,29 +885,14 @@ where
885
885
// and 483 * 705 ~= 341_000, and 341_000 < 400_000.
886
886
chan_utils:: MAX_STANDARD_TX_WEIGHT
887
887
} ;
888
+ // A 1-input 1-output transaction, both p2wpkh is 438 WU.
889
+ // If the coins go above this limit, it's ok we pop a few HTLCs and try again.
890
+ const USER_COINS_WEIGHT_BUDGET : u64 = 1000 ;
891
+
888
892
let mut broadcasted_htlcs = 0 ;
889
893
let mut batch_size = htlc_descriptors. len ( ) - broadcasted_htlcs;
890
894
891
895
while broadcasted_htlcs < htlc_descriptors. len ( ) {
892
- let htlcs = & htlc_descriptors[ broadcasted_htlcs..broadcasted_htlcs + batch_size] ;
893
- // Generate a new claim_id to map a user-provided utxo to this
894
- // particular set of HTLCs via `select_confirmed_utxos`.
895
- //
896
- // This matches the scheme used in `onchaintx.rs`, so for non-0fc-channels,
897
- // this should match the `ClaimId` of the claim generated in `onchaintx.rs`.
898
- let mut engine = Sha256 :: engine ( ) ;
899
- for htlc in htlcs {
900
- engine. input ( & htlc. commitment_txid . to_byte_array ( ) ) ;
901
- engine. input ( & htlc. htlc . transaction_output_index . unwrap ( ) . to_be_bytes ( ) ) ;
902
- }
903
- let utxo_id = ClaimId ( Sha256 :: from_engine ( engine) . to_byte_array ( ) ) ;
904
- log_info ! (
905
- self . logger,
906
- "Batch transaction assigned to UTXO id {} contains {} HTLCs: {}" ,
907
- log_bytes!( utxo_id. 0 ) ,
908
- htlcs. len( ) ,
909
- log_iter!( htlcs. iter( ) . map( |d| d. outpoint( ) ) )
910
- ) ;
911
896
let mut htlc_tx = Transaction {
912
897
version : if channel_type. supports_anchor_zero_fee_commitments ( ) {
913
898
Version :: non_standard ( 3 )
@@ -918,8 +903,20 @@ where
918
903
input : vec ! [ ] ,
919
904
output : vec ! [ ] ,
920
905
} ;
921
- let mut must_spend = Vec :: with_capacity ( htlcs. len ( ) ) ;
922
- for htlc_descriptor in htlcs {
906
+ let mut must_spend = Vec :: with_capacity ( htlc_descriptors. len ( ) - broadcasted_htlcs) ;
907
+ let mut htlc_weight_sum = 0 ;
908
+ for htlc_descriptor in
909
+ & htlc_descriptors[ broadcasted_htlcs..broadcasted_htlcs + batch_size]
910
+ {
911
+ let input_output_weight = if htlc_descriptor. preimage . is_some ( ) {
912
+ chan_utils:: htlc_success_input_output_pair_weight ( channel_type)
913
+ } else {
914
+ chan_utils:: htlc_timeout_input_output_pair_weight ( channel_type)
915
+ } ;
916
+ if htlc_weight_sum + input_output_weight >= max_weight - USER_COINS_WEIGHT_BUDGET {
917
+ break ;
918
+ }
919
+ htlc_weight_sum += input_output_weight;
923
920
let htlc_input = htlc_descriptor. unsigned_tx_input ( ) ;
924
921
must_spend. push ( Input {
925
922
outpoint : htlc_input. previous_output . clone ( ) ,
@@ -935,6 +932,30 @@ where
935
932
let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
936
933
htlc_tx. output . push ( htlc_output) ;
937
934
}
935
+ batch_size = htlc_tx. input . len ( ) ;
936
+ let selected_htlcs =
937
+ & htlc_descriptors[ broadcasted_htlcs..broadcasted_htlcs + batch_size] ;
938
+
939
+ let utxo_id = if broadcasted_htlcs == 0 {
940
+ claim_id
941
+ } else {
942
+ // Generate a new claim_id to map a user-provided utxo to this
943
+ // particular set of HTLCs via `select_confirmed_utxos`.
944
+ let mut engine = Sha256 :: engine ( ) ;
945
+ for htlc in selected_htlcs {
946
+ engine. input ( & htlc. commitment_txid . to_byte_array ( ) ) ;
947
+ engine. input ( & htlc. htlc . transaction_output_index . unwrap ( ) . to_be_bytes ( ) ) ;
948
+ }
949
+ ClaimId ( Sha256 :: from_engine ( engine) . to_byte_array ( ) )
950
+ } ;
951
+
952
+ log_info ! (
953
+ self . logger,
954
+ "Batch transaction assigned to UTXO id {} contains {} HTLCs: {}" ,
955
+ log_bytes!( utxo_id. 0 ) ,
956
+ batch_size,
957
+ log_iter!( selected_htlcs. iter( ) . map( |d| d. outpoint( ) ) )
958
+ ) ;
938
959
939
960
log_debug ! (
940
961
self . logger,
@@ -988,7 +1009,7 @@ where
988
1009
// construct psbt
989
1010
let mut htlc_psbt = Psbt :: from_unsigned_tx ( htlc_tx) . unwrap ( ) ;
990
1011
// add witness_utxo to htlc inputs
991
- for ( i, htlc_descriptor) in htlcs . iter ( ) . enumerate ( ) {
1012
+ for ( i, htlc_descriptor) in selected_htlcs . iter ( ) . enumerate ( ) {
992
1013
debug_assert_eq ! (
993
1014
htlc_psbt. unsigned_tx. input[ i] . previous_output,
994
1015
htlc_descriptor. outpoint( )
@@ -999,7 +1020,7 @@ where
999
1020
// add witness_utxo to remaining inputs
1000
1021
for ( idx, utxo) in coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( ) {
1001
1022
// offset to skip the htlc inputs
1002
- let index = idx + htlcs . len ( ) ;
1023
+ let index = idx + selected_htlcs . len ( ) ;
1003
1024
debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output, utxo. outpoint) ;
1004
1025
if utxo. output . script_pubkey . is_witness_program ( ) {
1005
1026
htlc_psbt. inputs [ index] . witness_utxo = Some ( utxo. output ) ;
@@ -1014,7 +1035,7 @@ where
1014
1035
let mut htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) . await ?;
1015
1036
1016
1037
let mut signers = BTreeMap :: new ( ) ;
1017
- for ( idx, htlc_descriptor) in htlcs . iter ( ) . enumerate ( ) {
1038
+ for ( idx, htlc_descriptor) in selected_htlcs . iter ( ) . enumerate ( ) {
1018
1039
let keys_id = htlc_descriptor. channel_derivation_parameters . keys_id ;
1019
1040
let signer = signers
1020
1041
. entry ( keys_id)
@@ -1101,6 +1122,7 @@ where
1101
1122
log_iter!( htlc_descriptors. iter( ) . map( |d| d. outpoint( ) ) )
1102
1123
) ;
1103
1124
self . handle_htlc_resolution (
1125
+ * claim_id,
1104
1126
* target_feerate_sat_per_1000_weight,
1105
1127
htlc_descriptors,
1106
1128
* tx_lock_time,
0 commit comments