Skip to content

Commit 1ed0638

Browse files
committed
Correct input comparison for input-subset RBF bump creation
This resolves a regression introduced in b461724 in which not all inputs are checked. Several opportunities to clarify and clean up comments are also taken.
1 parent e78d43a commit 1ed0638

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,31 +2394,39 @@ impl ChannelMonitor {
23942394
}
23952395

23962396
// Scan all input to verify is one of the outpoint spent is of interest for us
2397-
let mut claimed_outpoints = Vec::new();
2398-
let mut claimed_input_material = Vec::new();
2397+
let mut claimed_outputs_material = Vec::new();
23992398
for inp in &tx.input {
24002399
if let Some(ancestor_claimable_txid) = self.claimable_outpoints.get(&inp.previous_output) {
24012400
// If outpoint has claim request pending on it...
24022401
if let Some(claim_material) = self.pending_claim_requests.get_mut(&ancestor_claimable_txid.0) {
24032402
//... we need to verify equality between transaction outpoints and claim request
24042403
// outpoints to know if transaction is the original claim or a bumped one issued
24052404
// by us.
2406-
for claim_inp in claim_material.per_input_material.keys() {
2407-
if *claim_inp == inp.previous_output {
2408-
claimed_outpoints.push(inp.previous_output.clone());
2405+
let mut set_equality = true;
2406+
if claim_material.per_input_material.len() != tx.input.len() {
2407+
set_equality = false;
2408+
} else {
2409+
for (claim_inp, tx_inp) in claim_material.per_input_material.keys().zip(tx.input.iter()) {
2410+
if *claim_inp != tx_inp.previous_output {
2411+
set_equality = false;
2412+
}
24092413
}
24102414
}
2411-
if claimed_outpoints.len() == 0 && claim_material.per_input_material.len() == tx.input.len() { // If true, register claim request to be removed after reaching a block security height
2415+
2416+
// If this is our transaction (or our counterparty spent all the outputs
2417+
// before we could anyway), wait for ANTI_REORG_DELAY and clean the RBF
2418+
// tracking map.
2419+
if set_equality {
24122420
match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) {
24132421
hash_map::Entry::Occupied(_) => {},
24142422
hash_map::Entry::Vacant(entry) => {
24152423
entry.insert(vec![OnchainEvent::Claim { claim_request: ancestor_claimable_txid.0.clone()}]);
24162424
}
24172425
}
24182426
} else { // If false, generate new claim request with update outpoint set
2419-
for already_claimed in claimed_outpoints.iter() {
2420-
if let Some(input_material) = claim_material.per_input_material.remove(&already_claimed) {
2421-
claimed_input_material.push(input_material);
2427+
for input in tx.input.iter() {
2428+
if let Some(input_material) = claim_material.per_input_material.remove(&input.previous_output) {
2429+
claimed_outputs_material.push((input.previous_output, input_material));
24222430
}
24232431
}
24242432
//TODO: recompute soonest_timelock to avoid wasting a bit on fees
@@ -2430,11 +2438,11 @@ impl ChannelMonitor {
24302438
}
24312439
}
24322440
}
2433-
for (outpoint, input_material) in claimed_outpoints.iter().zip(claimed_input_material.drain(..)) {
2441+
for (outpoint, input_material) in claimed_outputs_material.drain(..) {
24342442
match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) {
24352443
hash_map::Entry::Occupied(_) => {},
24362444
hash_map::Entry::Vacant(entry) => {
2437-
entry.insert(vec![OnchainEvent::ContentiousOutpoint { outpoint: *outpoint, input_material: input_material }]);
2445+
entry.insert(vec![OnchainEvent::ContentiousOutpoint { outpoint, input_material }]);
24382446
}
24392447
}
24402448
}

0 commit comments

Comments
 (0)