@@ -174,7 +174,7 @@ impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
174
174
pub ( crate ) enum ExternalHTLCClaim {
175
175
/// The claim commonly referred to as the pre-signed second-stage HTLC transaction.
176
176
SecondStage {
177
- amount : u64 ,
177
+ amount_sats : u64 ,
178
178
per_commitment_number : u64 ,
179
179
redeem_script : Script ,
180
180
preimage : Option < PaymentPreimage > ,
@@ -681,7 +681,12 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
681
681
// outpoints to know if transaction is the original claim or a bumped one issued
682
682
// by us.
683
683
let mut set_equality = true ;
684
- if !request. requires_external_funding ( ) {
684
+ if !request. requires_external_funding ( ) ||
685
+ ( request. requires_external_funding ( ) && !request. is_malleable ( ) )
686
+ {
687
+ // If the claim does not require external funds to be allocated through
688
+ // additional inputs we can simply check the inputs in order as they
689
+ // cannot change under us.
685
690
if request. outpoints ( ) . len ( ) != tx. input . len ( ) {
686
691
set_equality = false ;
687
692
} else {
@@ -692,17 +697,17 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
692
697
}
693
698
}
694
699
} else {
695
- let request_inputs = request. outpoints ( ) ;
696
- let mut input_set = HashSet :: with_capacity ( request_inputs. len ( ) ) ;
697
- for input in request_inputs {
698
- let _ = input_set. insert ( input) ;
699
- }
700
- for tx_input in & tx. input {
701
- let _ = input_set. remove ( & tx_input. previous_output ) ;
702
- }
703
- if !input_set. is_empty ( ) {
704
- set_equality = false ;
700
+ // Otherwise, we'll do a linear search for each input (we don't expect
701
+ // large input sets to exist) to ensure the request's input set is fully
702
+ // spent to be resilient against the external claim reordering inputs.
703
+ let mut spends_all_inputs = true ;
704
+ for request_input in request. outpoints ( ) {
705
+ if tx. input . iter ( ) . find ( |input| input. previous_output == * request_input) . is_none ( ) {
706
+ spends_all_inputs = false ;
707
+ break ;
708
+ }
705
709
}
710
+ set_equality = spends_all_inputs;
706
711
}
707
712
708
713
macro_rules! clean_claim_request_after_safety_delay {
@@ -1026,7 +1031,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
1026
1031
& self . channel_transaction_parameters . as_holder_broadcastable ( ) , htlc_idx, preimage,
1027
1032
) ;
1028
1033
( htlc_tx, ExternalHTLCClaim :: SecondStage {
1029
- amount : htlc. amount_msat / 1000 ,
1034
+ amount_sats : htlc. amount_msat / 1000 ,
1030
1035
per_commitment_number : trusted_tx. commitment_number ( ) ,
1031
1036
redeem_script : chan_utils:: get_htlc_redeemscript_with_explicit_keys (
1032
1037
& htlc, self . opt_anchors ( ) , & trusted_tx. keys ( ) . broadcaster_htlc_key ,
0 commit comments