Skip to content

Commit 60f3c0a

Browse files
committed
DRY the comparison blocks in update_claims_view_from_matched_txn
In `update_claims_view_from_matched_txn` we have two different tx-equivalence checks which do the same thing - both check that the tx which appeared on chain spent all of the outpoints which we intended to spend in a given package. While one is more effecient than the other (but only usable in a subset of cases), the difference between O(N) and O(N^2) when N is 1-5 is trivial. Still, it is possible we hit this code with just shy of 900 HTLC outputs in a channel, and a transaction with a ton of inputs. While having to spin through a few million entries if our counterparty wastes a full block isn't really a big deal, we go ahead and use a sorted vec and binary searches because its trivial.
1 parent 399b3eb commit 60f3c0a

File tree

1 file changed

+5
-23
lines changed

1 file changed

+5
-23
lines changed

lightning/src/chain/onchaintx.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -733,31 +733,13 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
733733
// outpoints to know if transaction is the original claim or a bumped one issued
734734
// by us.
735735
let mut are_sets_equal = true;
736-
if !request.requires_external_funding() || !request.is_malleable() {
737-
// If the claim does not require external funds to be allocated through
738-
// additional inputs we can simply check the inputs in order as they
739-
// cannot change under us.
740-
if request.outpoints().len() != tx.input.len() {
736+
let mut tx_inputs = tx.input.iter().map(|input| &input.previous_output).collect::<Vec<_>>();
737+
tx_inputs.sort_unstable();
738+
for request_input in request.outpoints() {
739+
if tx_inputs.binary_search(&request_input).is_err() {
741740
are_sets_equal = false;
742-
} else {
743-
for (claim_inp, tx_inp) in request.outpoints().iter().zip(tx.input.iter()) {
744-
if **claim_inp != tx_inp.previous_output {
745-
are_sets_equal = false;
746-
}
747-
}
748-
}
749-
} else {
750-
// Otherwise, we'll do a linear search for each input (we don't expect
751-
// large input sets to exist) to ensure the request's input set is fully
752-
// spent to be resilient against the external claim reordering inputs.
753-
let mut spends_all_inputs = true;
754-
for request_input in request.outpoints() {
755-
if tx.input.iter().find(|input| input.previous_output == *request_input).is_none() {
756-
spends_all_inputs = false;
757-
break;
758-
}
741+
break;
759742
}
760-
are_sets_equal = spends_all_inputs;
761743
}
762744

763745
macro_rules! clean_claim_request_after_safety_delay {

0 commit comments

Comments
 (0)