Uh oh!
There was an error while loading. Please reload this page.
Avoid re-locking reused UTXO futures - #4673
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
No issues found. The implementation changed since my prior review pass (it now compares through the already-held guard via
One non-blocking observation (not a regression, and strictly better than the deadlock being fixed): with a reused future for the same SCID but a different announcement, there is a single |
fa1de66 to
0f8072fComparetnull
commented
Jun 11, 2026
Updated to line-wrap commit messages. |
TheBlueMatt
left a comment
There was a problem hiding this comment.
Not entirely sure anyone would ever implement it this way, but it seems the correct fix is to handle the duplicate with an Arc::ptr_eq check in check_replace_previous_entry, not unlock+relock.
ldk-reviews-bot
commented
Jun 12, 2026
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
UtxoLookup implementations may cache and return the same async future for repeated requests for a short channel id. When a replacement channel announcement arrives while that future is in-flight, the pending-entry comparison may point back to the future state already held by the async path. Detect that case with Arc::ptr_eq inside check_replace_previous_entry and compare against the held messages instead of taking the mutex again. This keeps duplicate-announcement filtering intact while letting replacement announcements update the pending entry without re-entering the lock. Co-Authored-By: HAL 9000 This finding was discovered by Project Loupe
0f8072f to
dce31b7Comparetnull
commented
Jun 17, 2026
Now updated with this approach. Let me know if you find that preferable, or if we should even consider not fixing this? |
TheBlueMatt
commented
Jun 17, 2026
IMO we should skip backporting this. I don't believe any of our implementations of the lookup interface will ever return the same future and implementing that interface by caching pending lookups and returning copies of the future seems like a lot of work that implementers aren't gonna do. LMK if you disagree @tnull |
tnull
commented
Jun 18, 2026
Fine by me. |
UtxoLookup implementations may cache and return the same async future for repeated requests for a short channel id. When a replacement channel announcement arrived for an in-flight lookup, the async path held the future state while comparing the existing pending entry, which could point to that same state.
Drop the state guard before checking or replacing the pending entry so repeated lookups can update the pending announcement without re-entering the mutex.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe