mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 23:08:36 +01:00
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.
This commit is contained in:
parent
399b3eb3f7
commit
60f3c0a206
1 changed files with 5 additions and 23 deletions
|
@ -733,31 +733,13 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
|
||||||
// outpoints to know if transaction is the original claim or a bumped one issued
|
// outpoints to know if transaction is the original claim or a bumped one issued
|
||||||
// by us.
|
// by us.
|
||||||
let mut are_sets_equal = true;
|
let mut are_sets_equal = true;
|
||||||
if !request.requires_external_funding() || !request.is_malleable() {
|
let mut tx_inputs = tx.input.iter().map(|input| &input.previous_output).collect::<Vec<_>>();
|
||||||
// If the claim does not require external funds to be allocated through
|
tx_inputs.sort_unstable();
|
||||||
// additional inputs we can simply check the inputs in order as they
|
for request_input in request.outpoints() {
|
||||||
// cannot change under us.
|
if tx_inputs.binary_search(&request_input).is_err() {
|
||||||
if request.outpoints().len() != tx.input.len() {
|
|
||||||
are_sets_equal = false;
|
are_sets_equal = false;
|
||||||
} else {
|
break;
|
||||||
for (claim_inp, tx_inp) in request.outpoints().iter().zip(tx.input.iter()) {
|
|
||||||
if **claim_inp != tx_inp.previous_output {
|
|
||||||
are_sets_equal = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Otherwise, we'll do a linear search for each input (we don't expect
|
|
||||||
// large input sets to exist) to ensure the request's input set is fully
|
|
||||||
// spent to be resilient against the external claim reordering inputs.
|
|
||||||
let mut spends_all_inputs = true;
|
|
||||||
for request_input in request.outpoints() {
|
|
||||||
if tx.input.iter().find(|input| input.previous_output == *request_input).is_none() {
|
|
||||||
spends_all_inputs = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
are_sets_equal = spends_all_inputs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! clean_claim_request_after_safety_delay {
|
macro_rules! clean_claim_request_after_safety_delay {
|
||||||
|
|
Loading…
Add table
Reference in a new issue