Skip to content

Conversation

TheBlueMatt
Copy link
Collaborator

In 0.1 (1481216) we started setting ChannelMonitorUpdate::update_id to a non-u64::MAX value for updates generated after a channel has been closed.

This is great, but in 71a364c we then started calculating the next update_id by incrementing the last update_id we saw when we started and were looking at the ChannelMonitor. However, the last-applied update_id may well be u64::MAX for old ChannelMonitors which were closed prior to 0.1. In that case the increment would overflow.

Here we fix this naively by simply replacing the increment with a saturating_add. While its possible this will result in a ChannelMonitorUpdate being tracked as in-flight (only for the ReleasePaymentComplete updates added in 71a364c) at the same update_id as other updates already in-flight and handling post-ChannelMonitorUpdate actions too early, this should only apply to releasing payment complete updates, which have no post-ChannelMonitorUpdate action.

Its also possible that this leads to a regression in the future, where we have some new post-closure update that does have a post-ChannelMonitorUpdate action and we run it too early, but by then presumably its fairly rare to have a ChannelMonitor for a channel closed pre-0.1 that still needs multiple updates.

@TheBlueMatt TheBlueMatt added this to the 0.2 milestone Sep 30, 2025
@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Sep 30, 2025

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

Copy link

codecov bot commented Sep 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.63%. Comparing base (54ed941) to head (dd21fce).
⚠️ Report is 20 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4136      +/-   ##
==========================================
+ Coverage   88.62%   88.63%   +0.01%     
==========================================
  Files         180      180              
  Lines      134895   135243     +348     
  Branches   134895   135243     +348     
==========================================
+ Hits       119546   119877     +331     
- Misses      12587    12600      +13     
- Partials     2762     2766       +4     
Flag Coverage Δ
fuzzing 21.76% <0.00%> (-0.01%) ⬇️
tests 88.48% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

.get_mut(&channel_id)
.expect("Channels originating a payment resolution must have a monitor");
*update_id += 1;
*update_id = update_id.saturating_add(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the current and future caveats described in the commit msg, does this need a log on overflow?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure if its really needed. Maybe the commit message isn't clear, but I don't see any issues with this with the current code. I do call out that its possible that other code changes in the future which introduces an issue, but I don't think we really need to log a warning on the assumption that future code might break really ancient channel closes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think the commit message is clear.

For someone looking at this statement though, it must be hard to understand why this is safe. I thought a warning log would both help debug any future issue with this, and at the same time add a bit more documentation. Or maybe move some of the commit message to a code comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still pretty thin and doesn't explain why it is okay to not increment when at the max already.

@ldk-reviews-bot
Copy link

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt TheBlueMatt force-pushed the 2025-09-update_id-overflow branch from 0813413 to ecc0da7 Compare October 7, 2025 12:29
wpaulino
wpaulino previously approved these changes Oct 7, 2025
In 0.1 (1481216) we started
setting `ChannelMonitorUpdate::update_id` to a non-`u64::MAX` value
for updates generated after a channel has been closed.

This is great, but in 71a364c we
then started calculating the next `update_id` by incrementing the
last `update_id` we saw when we started and were looking at the
`ChannelMonitor`. However, the last-applied `update_id` may well be
`u64::MAX` for old `ChannelMonitor`s which were closed prior to
0.1. In that case the increment would overflow.

Here we fix this naively by simply replacing the increment with a
`saturating_add`. While its possible this will result in a
`ChannelMonitorUpdate` being tracked as in-flight (only for the
`ReleasePaymentComplete` updates added in 71a364c)
at the same `update_id` as other updates already in-flight and
handling post-`ChannelMonitorUpdate` actions too early, this should
only apply to releasing payment complete updates, which have no
post-`ChannelMonitorUpdate` action.

Its also possible that this leads to a regression in the future,
where we have some new post-closure update that does have a
post-`ChannelMonitorUpdate` action and we run it too early, but by
then presumably its fairly rare to have a `ChannelMonitor` for a
channel closed pre-0.1 that still needs multiple updates.
.get_mut(&channel_id)
.expect("Channels originating a payment resolution must have a monitor");
*update_id += 1;
*update_id = update_id.saturating_add(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still pretty thin and doesn't explain why it is okay to not increment when at the max already.

@wpaulino wpaulino merged commit fec434b into lightningdevkit:main Oct 7, 2025
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants