Batch MPP claims into single ChannelMonitorUpdate#4552
Conversation
|
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
|
I've now thoroughly reviewed the entire PR diff and the surrounding codebase. Let me write my final review. Review SummaryPrior Issues StatusFixed since last review:
Still open from prior review (not re-posted as they remain relevant):
New ObservationsNo major new bugs or security issues found beyond what was previously flagged. The code improvements since the last review have addressed the most critical concerns. Minor observations:
|
395b30d to
88d62c4
Compare
88d62c4 to
5880633
Compare
|
🔔 1st Reminder Hey @jkczyz! This PR has been waiting for your review. |
5880633 to
d801ec9
Compare
It's intentionally left unused right now, pending any design decision that would be made for the msat values that field holds, in the case of a single claim, there's a
This is why that field exist, the absense of the direction it should take is the reason it is intentionally currently left unused. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4552 +/- ##
==========================================
+ Coverage 86.12% 86.36% +0.23%
==========================================
Files 157 158 +1
Lines 108922 109493 +571
Branches 108922 109493 +571
==========================================
+ Hits 93812 94561 +749
+ Misses 12495 12381 -114
+ Partials 2615 2551 -64
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
🔔 1st Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
|
🔔 3rd Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
TheBlueMatt
left a comment
There was a problem hiding this comment.
Hmm, would this not be simpler by using the holding cell instead? When we're failing, we call queue_fail_htlc which just shoves the failure into the holding cell then call check_free_peer_holding_cells to release them all at once. Rather than rebuilding that logic for claims, we should be able to do something similar. We'd have to handle the monitor updates with the preimages a bit differently, but not drastically so.
d801ec9 to
5992824
Compare
5992824 to
f466457
Compare
f466457 to
dddd924
Compare
086a669 to
2a28f1d
Compare
When multiple parts of an MPP payment arrive on the same channel, claim them via the holding cell so they are released as one combined ChannelMonitorUpdate (every PaymentPreimage step plus a single commitment_signed) instead of one round-trip per part. claim_payment_internal now forces the holding-cell path whenever there is more than one source, records each touched channel, and flushes them after queueing. The single-source case keeps the existing inline fast path. FundedChannel::get_update_fulfill_htlc gains a force_holding_cell flag that suppresses the per-claim ChannelMonitorUpdate so the flush can emit one combined update. When the holding cell cannot be freed immediately (awaiting RAA, monitor update in progress, disconnected, quiescent, ...), build_preimage_only_monitor_update writes a one-step preimage update so the preimage stays durable across restarts; the commitment_signed follows when the holding cell is naturally flushed. Update test_single_channel_multiple_mpp, test_simple_mpp, and auto_retry_partial_failure to reflect the new single-round-trip behavior, and drop the threaded reproducer that targeted the old per-claim path.
2a28f1d to
fc83c75
Compare
|
🔔 1st Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
| // When the caller asked us to push into the holding cell for batching | ||
| // (`force_holding_cell`) we skip producing a `ChannelMonitorUpdate` here; the caller is | ||
| // responsible for either flushing the holding cell (producing one combined update with | ||
| // every queued preimage and the commitment) or building a preimage-only update for |
There was a problem hiding this comment.
This is a massive layer violation - the ChannelManager shouldn't be making decisions around how to build ChannelMonitorUpdates, we shouldn't need a manual build_preimage_only_monitor_update, etc. Instead, we should be able to queue all the updates, then use the existing check_free_holding_cells logic (or check_free_peer_holding_cells to filter by the channels we actually updated) and have the channel automatically include the preimage updatesteps in the ChannelMonitorUpdate it builds.
When multiple parts of an MPP payment arrive on the same channel, claim them via the holding cell so they are released as one combined ChannelMonitorUpdate (every PaymentPreimage step plus a single commitment_signed) instead of one round-trip per part.
claim_payment_internal now forces the holding-cell path whenever there is more than one source, records each touched channel, and flushes them after queueing. The single-source case keeps the existing inline fast path.
FundedChannel::get_update_fulfill_htlc gains a force_holding_cell flag that suppresses the per-claim ChannelMonitorUpdate so the flush can emit one combined update. When the holding cell cannot be freed immediately (awaiting RAA, monitor update in progress, disconnected, quiescent, ...), build_preimage_only_monitor_update writes a one-step preimage update so the preimage stays durable across restarts; the commitment_signed follows when the holding cell is naturally flushed.
Update test_single_channel_multiple_mpp, test_simple_mpp, and auto_retry_partial_failure to reflect the new single-round-trip behavior, and drop the threaded reproducer that targeted the old per-claim path.
Tests has been updated to reflect this new batching of MPP claims
test_single_channel_multiple_mppauto_retry_partial_failuretest_keysend_dup_hash_partial_mppcloses #3986