Skip to content

Commit 35affd4

Browse files
committed
Maintain order of yielded claim events
Since the claim events are stored internally within a HashMap, they will be yielded in a random order once dispatched. Claim events may be invalidated if a conflicting claim has confirmed on-chain and we need to generate a new claim event; the randomized order could result in the new claim event being handled prior to the previous. To maintain the order in which the claim events are generated, we track them in a separate sequence vector.
1 parent ad8b3c9 commit 35affd4

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

lightning/src/chain/onchaintx.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,14 @@ pub struct OnchainTxHandler<ChannelSigner: Sign> {
247247
pub(crate) pending_claim_requests: HashMap<PackageID, PackageTemplate>,
248248
#[cfg(not(test))]
249249
pending_claim_requests: HashMap<PackageID, PackageTemplate>,
250+
251+
// Used to track external events that need to be forwarded to the `ChainMonitor`. We
252+
// additionally maintain an ordered sequence of the events as they occur, such that we don't
253+
// rely on the HashMap's randomized iterations.
250254
#[cfg(anchors)]
251255
pending_claim_events: HashMap<PackageID, ClaimEvent>,
256+
#[cfg(anchors)]
257+
pending_claim_events_sequence: Vec<PackageID>,
252258

253259
// Used to link outpoints claimed in a connected block to a pending claim request.
254260
// Key is outpoint than monitor parsing has detected we have keys/scripts to claim
@@ -409,6 +415,8 @@ impl<'a, K: KeysInterface> ReadableArgs<(&'a K, u64, [u8; 32])> for OnchainTxHan
409415
onchain_events_awaiting_threshold_conf,
410416
#[cfg(anchors)]
411417
pending_claim_events: HashMap::new(),
418+
#[cfg(anchors)]
419+
pending_claim_events_sequence: Vec::new(),
412420
secp_ctx,
413421
})
414422
}
@@ -430,7 +438,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
430438
onchain_events_awaiting_threshold_conf: Vec::new(),
431439
#[cfg(anchors)]
432440
pending_claim_events: HashMap::new(),
433-
441+
#[cfg(anchors)]
442+
pending_claim_events_sequence: Vec::new(),
434443
secp_ctx,
435444
}
436445
}
@@ -445,9 +454,19 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
445454

446455
#[cfg(anchors)]
447456
pub(crate) fn get_and_clear_pending_claim_events(&mut self) -> Vec<ClaimEvent> {
448-
let mut ret = HashMap::new();
449-
swap(&mut ret, &mut self.pending_claim_events);
450-
ret.into_iter().map(|(_, event)| event).collect::<Vec<_>>()
457+
let mut set = HashMap::new();
458+
swap(&mut set, &mut self.pending_claim_events);
459+
let mut sequence = Vec::new();
460+
swap(&mut sequence, &mut self.pending_claim_events_sequence);
461+
462+
let mut pending_claim_events = Vec::with_capacity(set.len());
463+
for package_id in &sequence {
464+
if !set.contains_key(package_id) {
465+
continue;
466+
}
467+
pending_claim_events.push(set.remove(package_id).unwrap());
468+
}
469+
pending_claim_events
451470
}
452471

453472
/// Lightning security model (i.e being able to redeem/timeout HTLC or penalize counterparty
@@ -692,6 +711,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
692711
},
693712
};
694713
self.pending_claim_events.insert(package_id, claim_event);
714+
self.pending_claim_events_sequence.push(package_id);
695715
package_id
696716
},
697717
};
@@ -813,6 +833,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
813833
self.claimable_outpoints.remove(&outpoint);
814834
#[cfg(anchors)]
815835
self.pending_claim_events.remove(&package_id);
836+
#[cfg(anchors)]
837+
self.pending_claim_events_sequence.retain(|id| *id != package_id);
816838
}
817839
}
818840
},
@@ -849,6 +871,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
849871
OnchainClaim::Event(claim_event) => {
850872
log_info!(logger, "Yielding RBF-bumped onchain event to spend inputs {:?}", request.outpoints());
851873
self.pending_claim_events.insert(*first_claim_txid, claim_event);
874+
self.pending_claim_events_sequence.push(*first_claim_txid);
852875
},
853876
}
854877
if let Some(request) = self.pending_claim_requests.get_mut(first_claim_txid) {

0 commit comments

Comments
 (0)