Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8beea92
Correct gossip forwarding criteria while doing background sync
TheBlueMatt Sep 22, 2025
9501d82
Immediately archive `ChannelMonitor`s for inbound unfuned channels
TheBlueMatt Sep 18, 2025
50e42fc
Speed up `remove_stale_channels_and_tracking` nontrivially
TheBlueMatt Sep 17, 2025
560f17c
Speed up `remove_stale_channels_and_tracking` nontrivially
TheBlueMatt Sep 17, 2025
6aa7d87
Don't auto-fail offers payments pre-HTLC lock in
valentinewallace Sep 17, 2025
1ba558e
Introduce get_and_clear_pending_raa_blockers
shaavan Jan 3, 2025
6b90033
Introduce RAA Blocker check in Node::drop()
shaavan Jan 3, 2025
1accc19
Ensure partial MPP claims continue to blocks channels on restart
TheBlueMatt Jul 14, 2025
f440be2
Marginally simplify types for req'd `counterparty_node_id` in claim
TheBlueMatt Aug 4, 2025
5da552c
f add back missing comment deletion
TheBlueMatt Oct 9, 2025
f1b0498
Add a `counterparty_node_id` to `ClaimedHTLC` in claimed events
TheBlueMatt Aug 4, 2025
769e5e7
Stop using RAA-unblocking post event action chan funding outpoints
TheBlueMatt Aug 4, 2025
d134cb0
Block RAA `ChannelMonitorUpdate`s on `PaymentClaimed` events
TheBlueMatt Aug 4, 2025
9fb9acc
Correct `test_dup_htlc_onchain_doesnt_fail_on_reload`
TheBlueMatt Jul 31, 2025
46f5754
Make `ChannelMonitor` round-trip tests more robust
TheBlueMatt Aug 1, 2025
24090fa
Rebuild pending payments list before replaying pending claims/fails
TheBlueMatt Oct 5, 2025
30748ad
f clarify upstream -> 0.1 diff
TheBlueMatt Oct 9, 2025
a3f3e24
Store preimages we learned on chain in case of `MonitorEvent` loss
TheBlueMatt Jul 20, 2025
26da7a2
`rustfmt` and clean up `get_onchain_failed_outbound_htlcs`
TheBlueMatt Aug 1, 2025
67dbad5
Re-fail perm-failed HTLCs on startup in case of `MonitorEvent` loss
TheBlueMatt Aug 1, 2025
7045345
Add a new `ChannelMoniorUpdateStep::ReleasePaymentComplete`
TheBlueMatt Jul 30, 2025
a253809
Prepare to provide new `ReleasePaymentComplete` monitor updates
TheBlueMatt Aug 2, 2025
0ed5c5e
Generate new `ReleasePaymentComplete` monitor updates
TheBlueMatt Aug 2, 2025
da2bc67
f clearer log
TheBlueMatt Oct 9, 2025
2b9390f
Stop re-hydrating pending payments once they are fully resolved
TheBlueMatt Aug 2, 2025
e4dab7a
Properly provide `PaymentPathSuccessful` event for replay claims
TheBlueMatt Aug 1, 2025
51451b9
draft release notes
TheBlueMatt Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
# 0.1.6 - Oct XXX, 2025 - "Async Preimage Claims"

## Performance Improvements
* `NetworkGraph::remove_stale_channels_and_tracking` has been sped up by more
than 20x in cases where many entries need to be removed (such as after
initial gossip sync, #4080).

## Bug Fixes
* Delivery of on-chain resolutions of HTLCs to `ChannelManager` has been made
more robust to prevent loss in some exceedingly rare crash cases. This may
marginally increase payment resolution event replays on startup (#3984).
* Corrected forwarding of new gossip to peers which we are sending an initial
gossip sync to (#4107).
* A rare race condition may have resulted in outbound BOLT12 payments
spuriously failing while processing the `Bolt12Invoice` message (#4078).
* If a channel is updated multiple times after a payment is claimed while using
async persistence of the `ChannelMonitorUpdate`s, and the node then restarts
with a stale copy of its `ChannelManager`, the `PaymentClaimed` may have been
lost (#3988).
* If an async-persisted `ChannelMonitorUpdate` for one part of an MPP claim
does not complete before multiple `ChannelMonitorUpdate`s for another channel
in the same MPP claim complete, and the node restarts twice, the preimage may
be lost and the part of the MPP payment not claimed (#3928).

## Security
0.1.6 fixes a denial of service vulnerability and a funds-theft vulnerability.
* When a channel has been force-closed, we have already claimed some of its
HTLCs on-chain, and we later learn a new preimage allowing us to claim
further HTLCs on-chain, we could in some cases generate invalid claim
transactions leading to loss of funds (#XXX).
* When a `ChannelMonitor` is created for a channel which is never funded with
a real transaction, `ChannelMonitor::get_claimable_balances` would never be
empty. As a result, `ChannelMonitor::check_and_update_full_resolution_status`
would never indicate the monitor is prunable, and thus
`ChainMonitor::archive_fully_resolved_channel_monitors` would never remove
it. This allows a peer which opens channels without funding them to bloat our
memory and disk space, eventually leading to denial-of-service (#4081).

# 0.1.5 - Jul 16, 2025 - "Async Path Reduction"

## Performance Improvements
Expand Down
309 changes: 211 additions & 98 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

46 changes: 45 additions & 1 deletion lightning/src/chain/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ enum PackageMalleability {
///
/// As packages are time-sensitive, we fee-bump and rebroadcast them at scheduled intervals.
/// Failing to confirm a package translate as a loss of funds for the user.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Eq)]
pub struct PackageTemplate {
// List of onchain outputs and solving data to generate satisfying witnesses.
inputs: Vec<(BitcoinOutPoint, PackageSolvingData)>,
Expand Down Expand Up @@ -849,6 +849,50 @@ pub struct PackageTemplate {
height_timer: u32,
}

impl PartialEq for PackageTemplate {
fn eq(&self, o: &Self) -> bool {
if self.inputs != o.inputs
|| self.malleability != o.malleability
|| self.feerate_previous != o.feerate_previous
|| self.height_timer != o.height_timer
{
return false;
}
#[cfg(test)]
{
// In some cases we may reset `counterparty_spendable_height` to zero on reload, which
// can cause our test assertions that ChannelMonitors round-trip exactly to trip. Here
// we allow exactly the same case as we tweak in the `PackageTemplate` `Readable`
// implementation.
if self.counterparty_spendable_height == 0 {
for (_, input) in self.inputs.iter() {
if let PackageSolvingData::RevokedHTLCOutput(RevokedHTLCOutput {
htlc, ..
}) = input
{
if !htlc.offered && htlc.cltv_expiry != 0 {
return true;
}
}
}
}
if o.counterparty_spendable_height == 0 {
for (_, input) in o.inputs.iter() {
if let PackageSolvingData::RevokedHTLCOutput(RevokedHTLCOutput {
htlc, ..
}) = input
{
if !htlc.offered && htlc.cltv_expiry != 0 {
return true;
}
}
}
}
}
self.counterparty_spendable_height == o.counterparty_spendable_height
}
}

impl PackageTemplate {
pub(crate) fn can_merge_with(&self, other: &PackageTemplate, cur_height: u32) -> bool {
match (self.malleability, other.malleability) {
Expand Down
6 changes: 6 additions & 0 deletions lightning/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ impl_writeable_tlv_based_enum_legacy!(PaymentPurpose,
/// Information about an HTLC that is part of a payment that can be claimed.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClaimedHTLC {
/// The counterparty of the channel.
///
/// This value will always be `None` for objects serialized with LDK versions prior to 0.2 and
/// `Some` otherwise.
pub counterparty_node_id: Option<PublicKey>,
/// The `channel_id` of the channel over which the HTLC was received.
pub channel_id: ChannelId,
/// The `user_channel_id` of the channel over which the HTLC was received. This is the value
Expand Down Expand Up @@ -259,6 +264,7 @@ impl_writeable_tlv_based!(ClaimedHTLC, {
(0, channel_id, required),
(1, counterparty_skimmed_fee_msat, (default_value, 0u64)),
(2, user_channel_id, required),
(3, counterparty_node_id, option),
(4, cltv_expiry, required),
(6, value_msat, required),
});
Expand Down
Loading
Loading