@@ -41,6 +41,8 @@ use crate::util::logger::Logger;
41
41
use bitcoin:: amount:: Amount ;
42
42
use bitcoin:: consensus:: Encodable ;
43
43
use bitcoin:: constants:: WITNESS_SCALE_FACTOR ;
44
+ use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
45
+ use bitcoin:: hashes:: { Hash , HashEngine } ;
44
46
use bitcoin:: locktime:: absolute:: LockTime ;
45
47
use bitcoin:: secp256k1;
46
48
use bitcoin:: secp256k1:: ecdsa:: Signature ;
@@ -847,24 +849,13 @@ where
847
849
/// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
848
850
/// fully-signed, fee-bumped HTLC transaction that is broadcast to the network.
849
851
async fn handle_htlc_resolution (
850
- & self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
851
- htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : LockTime ,
852
+ & self , target_feerate_sat_per_1000_weight : u32 , htlc_descriptors : & [ HTLCDescriptor ] ,
853
+ tx_lock_time : LockTime ,
852
854
) -> Result < ( ) , ( ) > {
853
855
let channel_type = & htlc_descriptors[ 0 ]
854
856
. channel_derivation_parameters
855
857
. transaction_parameters
856
858
. channel_type_features ;
857
- let mut htlc_tx = Transaction {
858
- version : if channel_type. supports_anchor_zero_fee_commitments ( ) {
859
- Version :: non_standard ( 3 )
860
- } else {
861
- Version :: TWO
862
- } ,
863
- lock_time : tx_lock_time,
864
- input : vec ! [ ] ,
865
- output : vec ! [ ] ,
866
- } ;
867
- let mut must_spend = Vec :: with_capacity ( htlc_descriptors. len ( ) ) ;
868
859
let ( htlc_success_witness_weight, htlc_timeout_witness_weight) =
869
860
if channel_type. supports_anchor_zero_fee_commitments ( ) {
870
861
(
@@ -879,123 +870,181 @@ where
879
870
} else {
880
871
panic ! ( "channel type should be either zero-fee HTLCs, or zero-fee commitments" ) ;
881
872
} ;
882
- for htlc_descriptor in htlc_descriptors {
883
- let htlc_input = htlc_descriptor. unsigned_tx_input ( ) ;
884
- must_spend. push ( Input {
885
- outpoint : htlc_input. previous_output . clone ( ) ,
886
- previous_utxo : htlc_descriptor. previous_utxo ( & self . secp ) ,
887
- satisfaction_weight : EMPTY_SCRIPT_SIG_WEIGHT
888
- + if htlc_descriptor. preimage . is_some ( ) {
889
- htlc_success_witness_weight
890
- } else {
891
- htlc_timeout_witness_weight
892
- } ,
893
- } ) ;
894
- htlc_tx. input . push ( htlc_input) ;
895
- let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
896
- htlc_tx. output . push ( htlc_output) ;
897
- }
898
873
899
- log_debug ! (
900
- self . logger,
901
- "Performing coin selection for HTLC transaction targeting {} sat/kW" ,
902
- target_feerate_sat_per_1000_weight
903
- ) ;
874
+ let max_weight = if channel_type. supports_anchor_zero_fee_commitments ( ) {
875
+ // Cap the size of transactions claiming `HolderHTLCOutput` in 0FC channels.
876
+ // Otherwise, we could hit the max 10_000vB size limit on V3 transactions
877
+ // (BIP 431 rule 4).
878
+ chan_utils:: TRUC_MAX_WEIGHT
879
+ } else {
880
+ u64:: MAX
881
+ } ;
882
+ let mut broadcasted_htlcs = 0 ;
883
+ let mut batch_size = htlc_descriptors. len ( ) - broadcasted_htlcs;
884
+
885
+ while broadcasted_htlcs < htlc_descriptors. len ( ) {
886
+ let htlcs = & htlc_descriptors[ broadcasted_htlcs..broadcasted_htlcs + batch_size] ;
887
+ // Generate a new claim_id to map a user-provided utxo to this
888
+ // particular set of HTLCs via `select_confirmed_utxos`.
889
+ //
890
+ // This matches the scheme used in `onchaintx.rs`, so for non-0fc-channels,
891
+ // this should match the `ClaimId` of the claim generated in `onchaintx.rs`.
892
+ let mut engine = Sha256 :: engine ( ) ;
893
+ for htlc in htlcs {
894
+ engine. input ( & htlc. commitment_txid . to_byte_array ( ) ) ;
895
+ engine. input ( & htlc. htlc . transaction_output_index . unwrap ( ) . to_be_bytes ( ) ) ;
896
+ }
897
+ let utxo_id = ClaimId ( Sha256 :: from_engine ( engine) . to_byte_array ( ) ) ;
898
+ log_info ! (
899
+ self . logger,
900
+ "Batch transaction assigned to UTXO id {} contains {} HTLCs: {}" ,
901
+ log_bytes!( utxo_id. 0 ) ,
902
+ htlcs. len( ) ,
903
+ log_iter!( htlcs. iter( ) . map( |d| d. outpoint( ) ) )
904
+ ) ;
905
+ let mut htlc_tx = Transaction {
906
+ version : if channel_type. supports_anchor_zero_fee_commitments ( ) {
907
+ Version :: non_standard ( 3 )
908
+ } else {
909
+ Version :: TWO
910
+ } ,
911
+ lock_time : tx_lock_time,
912
+ input : vec ! [ ] ,
913
+ output : vec ! [ ] ,
914
+ } ;
915
+ let mut must_spend = Vec :: with_capacity ( htlcs. len ( ) ) ;
916
+ for htlc_descriptor in htlcs {
917
+ let htlc_input = htlc_descriptor. unsigned_tx_input ( ) ;
918
+ must_spend. push ( Input {
919
+ outpoint : htlc_input. previous_output . clone ( ) ,
920
+ previous_utxo : htlc_descriptor. previous_utxo ( & self . secp ) ,
921
+ satisfaction_weight : EMPTY_SCRIPT_SIG_WEIGHT
922
+ + if htlc_descriptor. preimage . is_some ( ) {
923
+ htlc_success_witness_weight
924
+ } else {
925
+ htlc_timeout_witness_weight
926
+ } ,
927
+ } ) ;
928
+ htlc_tx. input . push ( htlc_input) ;
929
+ let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
930
+ htlc_tx. output . push ( htlc_output) ;
931
+ }
904
932
905
- #[ cfg( debug_assertions) ]
906
- let must_spend_satisfaction_weight =
907
- must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum :: < u64 > ( ) ;
908
- #[ cfg( debug_assertions) ]
909
- let must_spend_amount =
910
- must_spend. iter ( ) . map ( |input| input. previous_utxo . value . to_sat ( ) ) . sum :: < u64 > ( ) ;
933
+ log_debug ! (
934
+ self . logger,
935
+ "Performing coin selection for HTLC transaction targeting {} sat/kW" ,
936
+ target_feerate_sat_per_1000_weight
937
+ ) ;
911
938
912
- let coin_selection: CoinSelection = self
913
- . utxo_source
914
- . select_confirmed_utxos (
915
- claim_id,
916
- must_spend,
917
- & htlc_tx. output ,
918
- target_feerate_sat_per_1000_weight,
919
- )
920
- . await ?;
921
-
922
- #[ cfg( debug_assertions) ]
923
- let input_satisfaction_weight: u64 =
924
- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum ( ) ;
925
- #[ cfg( debug_assertions) ]
926
- let total_satisfaction_weight = must_spend_satisfaction_weight + input_satisfaction_weight;
927
- #[ cfg( debug_assertions) ]
928
- let input_value: u64 =
929
- coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value . to_sat ( ) ) . sum ( ) ;
930
- #[ cfg( debug_assertions) ]
931
- let total_input_amount = must_spend_amount + input_value;
932
-
933
- self . process_coin_selection ( & mut htlc_tx, & coin_selection) ;
934
-
935
- // construct psbt
936
- let mut htlc_psbt = Psbt :: from_unsigned_tx ( htlc_tx) . unwrap ( ) ;
937
- // add witness_utxo to htlc inputs
938
- for ( i, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
939
- debug_assert_eq ! (
940
- htlc_psbt. unsigned_tx. input[ i] . previous_output,
941
- htlc_descriptor. outpoint( )
939
+ let must_spend_satisfaction_weight =
940
+ must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum :: < u64 > ( ) ;
941
+ #[ cfg( debug_assertions) ]
942
+ let must_spend_amount =
943
+ must_spend. iter ( ) . map ( |input| input. previous_utxo . value . to_sat ( ) ) . sum :: < u64 > ( ) ;
944
+
945
+ let coin_selection: CoinSelection = self
946
+ . utxo_source
947
+ . select_confirmed_utxos (
948
+ utxo_id,
949
+ must_spend,
950
+ & htlc_tx. output ,
951
+ target_feerate_sat_per_1000_weight,
952
+ )
953
+ . await ?;
954
+
955
+ let input_satisfaction_weight: u64 =
956
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. satisfaction_weight ) . sum ( ) ;
957
+ let total_satisfaction_weight =
958
+ must_spend_satisfaction_weight + input_satisfaction_weight;
959
+
960
+ #[ cfg( debug_assertions) ]
961
+ let input_value: u64 =
962
+ coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value . to_sat ( ) ) . sum ( ) ;
963
+ #[ cfg( debug_assertions) ]
964
+ let total_input_amount = must_spend_amount + input_value;
965
+
966
+ self . process_coin_selection ( & mut htlc_tx, & coin_selection) ;
967
+
968
+ let unsigned_tx_weight =
969
+ htlc_tx. weight ( ) . to_wu ( ) - ( htlc_tx. input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
970
+ let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
971
+ if expected_signed_tx_weight >= max_weight {
972
+ let extra_weight = expected_signed_tx_weight - max_weight;
973
+ let htlcs_to_remove = ( extra_weight / chan_utils:: htlc_timeout_tx_weight ( channel_type)
974
+ // If we remove extra_weight / timeout_weight + 1 we sometimes still land above max_weight
975
+ + 2 ) as usize ;
976
+ batch_size = batch_size. checked_sub ( htlcs_to_remove) . ok_or ( ( ) ) ?;
977
+ continue ;
978
+ }
979
+ broadcasted_htlcs += batch_size;
980
+ batch_size = htlc_descriptors. len ( ) - broadcasted_htlcs;
981
+
982
+ // construct psbt
983
+ let mut htlc_psbt = Psbt :: from_unsigned_tx ( htlc_tx) . unwrap ( ) ;
984
+ // add witness_utxo to htlc inputs
985
+ for ( i, htlc_descriptor) in htlcs. iter ( ) . enumerate ( ) {
986
+ debug_assert_eq ! (
987
+ htlc_psbt. unsigned_tx. input[ i] . previous_output,
988
+ htlc_descriptor. outpoint( )
989
+ ) ;
990
+ htlc_psbt. inputs [ i] . witness_utxo = Some ( htlc_descriptor. previous_utxo ( & self . secp ) ) ;
991
+ }
992
+
993
+ // add witness_utxo to remaining inputs
994
+ for ( idx, utxo) in coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( ) {
995
+ // offset to skip the htlc inputs
996
+ let index = idx + htlcs. len ( ) ;
997
+ debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output, utxo. outpoint) ;
998
+ if utxo. output . script_pubkey . is_witness_program ( ) {
999
+ htlc_psbt. inputs [ index] . witness_utxo = Some ( utxo. output ) ;
1000
+ }
1001
+ }
1002
+
1003
+ log_debug ! (
1004
+ self . logger,
1005
+ "Signing HTLC transaction {}" ,
1006
+ htlc_psbt. unsigned_tx. compute_txid( )
942
1007
) ;
943
- htlc_psbt. inputs [ i] . witness_utxo = Some ( htlc_descriptor. previous_utxo ( & self . secp ) ) ;
944
- }
945
- // add witness_utxo to remaining inputs
946
- for ( idx, utxo) in coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( ) {
947
- // offset to skip the htlc inputs
948
- let index = idx + htlc_descriptors. len ( ) ;
949
- debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output, utxo. outpoint) ;
950
- if utxo. output . script_pubkey . is_witness_program ( ) {
951
- htlc_psbt. inputs [ index] . witness_utxo = Some ( utxo. output ) ;
1008
+ let mut htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) . await ?;
1009
+
1010
+ let mut signers = BTreeMap :: new ( ) ;
1011
+ for ( idx, htlc_descriptor) in htlcs. iter ( ) . enumerate ( ) {
1012
+ let keys_id = htlc_descriptor. channel_derivation_parameters . keys_id ;
1013
+ let signer = signers
1014
+ . entry ( keys_id)
1015
+ . or_insert_with ( || self . signer_provider . derive_channel_signer ( keys_id) ) ;
1016
+ let htlc_sig = signer. sign_holder_htlc_transaction (
1017
+ & htlc_tx,
1018
+ idx,
1019
+ htlc_descriptor,
1020
+ & self . secp ,
1021
+ ) ?;
1022
+ let witness_script = htlc_descriptor. witness_script ( & self . secp ) ;
1023
+ htlc_tx. input [ idx] . witness =
1024
+ htlc_descriptor. tx_input_witness ( & htlc_sig, & witness_script) ;
952
1025
}
953
- }
954
1026
955
- #[ cfg( debug_assertions) ]
956
- let unsigned_tx_weight = htlc_psbt. unsigned_tx . weight ( ) . to_wu ( )
957
- - ( htlc_psbt. unsigned_tx . input . len ( ) as u64 * EMPTY_SCRIPT_SIG_WEIGHT ) ;
1027
+ #[ cfg( debug_assertions) ]
1028
+ {
1029
+ let signed_tx_weight = htlc_tx. weight ( ) . to_wu ( ) ;
1030
+ // Our estimate should be within a 2% error margin of the actual weight and we should
1031
+ // never underestimate.
1032
+ assert ! ( expected_signed_tx_weight >= signed_tx_weight) ;
1033
+ assert ! ( expected_signed_tx_weight * 98 / 100 <= signed_tx_weight) ;
958
1034
959
- log_debug ! (
960
- self . logger,
961
- "Signing HTLC transaction {}" ,
962
- htlc_psbt. unsigned_tx. compute_txid( )
963
- ) ;
964
- htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) . await ?;
965
-
966
- let mut signers = BTreeMap :: new ( ) ;
967
- for ( idx, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
968
- let keys_id = htlc_descriptor. channel_derivation_parameters . keys_id ;
969
- let signer = signers
970
- . entry ( keys_id)
971
- . or_insert_with ( || self . signer_provider . derive_channel_signer ( keys_id) ) ;
972
- let htlc_sig =
973
- signer. sign_holder_htlc_transaction ( & htlc_tx, idx, htlc_descriptor, & self . secp ) ?;
974
- let witness_script = htlc_descriptor. witness_script ( & self . secp ) ;
975
- htlc_tx. input [ idx] . witness =
976
- htlc_descriptor. tx_input_witness ( & htlc_sig, & witness_script) ;
977
- }
1035
+ let expected_signed_tx_fee =
1036
+ fee_for_weight ( target_feerate_sat_per_1000_weight, signed_tx_weight) ;
1037
+ let signed_tx_fee = total_input_amount
1038
+ - htlc_tx. output . iter ( ) . map ( |output| output. value . to_sat ( ) ) . sum :: < u64 > ( ) ;
1039
+ // Our feerate should always be at least what we were seeking. It may overshoot if
1040
+ // the coin selector burned funds to an OP_RETURN without a change output.
1041
+ assert ! ( signed_tx_fee >= expected_signed_tx_fee) ;
1042
+ }
978
1043
979
- #[ cfg( debug_assertions) ]
980
- {
981
- let signed_tx_weight = htlc_tx. weight ( ) . to_wu ( ) ;
982
- let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
983
- // Our estimate should be within a 1% error margin of the actual weight and we should
984
- // never underestimate.
985
- assert ! ( expected_signed_tx_weight >= signed_tx_weight) ;
986
- assert ! ( expected_signed_tx_weight * 99 / 100 <= signed_tx_weight) ;
987
-
988
- let expected_signed_tx_fee =
989
- fee_for_weight ( target_feerate_sat_per_1000_weight, signed_tx_weight) ;
990
- let signed_tx_fee = total_input_amount
991
- - htlc_tx. output . iter ( ) . map ( |output| output. value . to_sat ( ) ) . sum :: < u64 > ( ) ;
992
- // Our feerate should always be at least what we were seeking. It may overshoot if
993
- // the coin selector burned funds to an OP_RETURN without a change output.
994
- assert ! ( signed_tx_fee >= expected_signed_tx_fee) ;
1044
+ log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
1045
+ self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
995
1046
}
996
1047
997
- log_info ! ( self . logger, "Broadcasting {}" , log_tx!( htlc_tx) ) ;
998
- self . broadcaster . broadcast_transactions ( & [ & htlc_tx] ) ;
999
1048
Ok ( ( ) )
1000
1049
}
1001
1050
@@ -1046,7 +1095,6 @@ where
1046
1095
log_iter!( htlc_descriptors. iter( ) . map( |d| d. outpoint( ) ) )
1047
1096
) ;
1048
1097
self . handle_htlc_resolution (
1049
- * claim_id,
1050
1098
* target_feerate_sat_per_1000_weight,
1051
1099
htlc_descriptors,
1052
1100
* tx_lock_time,
0 commit comments