Every captured commit receives deterministic security triage and a separate communication-quality score. Security candidates and broader second-pass signals receive full-patch Ollama analysis.
Message quality measures whether a commit identifies its scope, purpose, rationale, testing, and supporting references. It does not change the security-severity score.
This commit rewrites how a Lightning wallet talks to Esplora block-explorer servers so that many status checks happen in parallel instead of one at a time. It is a performance/refactoring change. There is no direct evidence in the commit t…
Concurrency/timing change in transaction confirmation logicNew inconsistency check preserved when a previously-confirmed tx is reported unconfirmedAdded defensive error path for missing pre-fetched block status
This change stops the Electrum-based transaction sync client from downloading the very transaction that created an output it is watching. Previously, the client could request that transaction from Electrum, even though a transaction can ne…
Avoids unnecessary Electrum transaction.get requests for watched outputsReduces information disclosure to Electrum server about watched outpointsAdds regression test verifying request suppression
This change improves how the Lightning Dev Kit's Electrum and Esplora transaction-sync clients track watched Bitcoin transactions. Previously, the code ignored the script pubkey (the 'address' associated with a transaction) supplied when r…
Previously ignored `script_pubkey` argument in `register_tx` for transaction watchersElectrum script-history queries previously used an arbitrary transaction output, which could be OP_RETURN and therefore unindexed by some Electrum serversNew logic prefers caller-supplied script pubkey and falls back to non-OP_RETURN outputs
This commit changes how LDK stores pending event notifications. It adds serialization support for several event types that previously were not fully saved to disk, and introduces a helper method so the code can decide which events are wort…
Data-loss prevention: previously non-round-trippable event variants are now fully serialized, avoiding accidental event loss when users serialize Event queues themselvesState-consistency hardening: ChannelManager now explicitly skips events that describe non-surviving restart state, preventing replay of stale eventsDefensive assertion: debug builds assert that every persisted event round-trips to Some(event), catching serialization mismatches
This commit only adds documentation comments to two source files. It explains that certain funding-signing events can become stale if the underlying negotiation fails, and that callers may see specific harmless errors as a result. No code …
This commit removes a fixed-version pin for the honggfuzz fuzzing tool in a continuous-integration script. The project now uses the current release of honggfuzz instead of an older pinned version. There is no change to the actual Lightning…
This commit changes the Rust toolchain used in the continuous integration (CI) fuzzing job from a fixed older version (1.75) to the latest stable release. It is purely a build/test infrastructure change to fix a dependency compatibility is…
This commit makes a previously internal helper function public so that outside developers can build dummy-hop tails for blinded payment paths without recreating the logic themselves. It is an API usability change, not a fix for a known sec…
No security-relevant behavior change in the diffAPI visibility broadened from crate-public to publicCLTV expiry overflow check already present and unchanged
This change adds a safety check in a Bitcoin Lightning Network library (LDK). Previously, if the software tried to verify a peer's commitment signature before it had learned the peer's channel parameters, it could crash with a panic. Now i…
Defensive check added on peer-driven code path to prevent panicMissing counterparty_parameters could previously cause panic during commitment transaction constructionChannel closure returned instead of panic
This commit only changes the wording of an error message sent to peers when a commitment transaction fails validation. It replaces the vague phrase 'Failed to validate our commitment' with the clearer 'Received commitment failed validation…
This commit moves the checks that validate a counterparty's signatures on the holder's commitment and HTLC transactions out of the general channel code and into the signer module (InMemorySigner). Previously, these signature checks were do…
Moved signature validation from channel state machine into signer moduleAdded new tests that corrupt signatures and verify rejectionChanged error message from 'Invalid commitment tx signature from peer' / 'Invalid funding_created signature from peer' to 'Failed to validate our commitment'
This change fixes a Lightning channel splicing bug: when two peers temporarily disconnect during a splice, any half-finished signature the other side already sent is now discarded. Before the fix, that stale signature could be reused after…
State-invalidation bug in multi-step protocol (splice negotiation)Stale cryptographic signature not cleared on disconnectPotential reuse of old commitment state after reconnect
This fix prevents a Lightning channel from being accidentally force-closed. During a splice (a way to resize a payment channel), one side's initial signature could be kept in memory after the peers disconnected. If the peers later reconnec…
State inconsistency: in-memory buffered message not cleared on disconnectDuplicate message processing after reconnectionForce-close consequence for active Lightning channel
This commit is a simple rename of a public function from `matches_invoice_signing_pubkey` to `key_can_sign_invoice`, plus matching updates to its documentation, callers, tests, and changelog. No behavior changed. It is not a security fix.
This commit is a simple rename of a function and its documentation from matches_invoice_signing_pubkey to key_can_sign_invoice. No logic, behavior, or security properties changed. It is a follow-up code-review naming cleanup.
This commit adds a new public helper method, Offer::matches_invoice_signed_by (later renamed matches_invoice_signing_pubkey), that lets callers check whether an invoice signing key belongs to the recipient named by a BOLT 12 offer. It also…
Refactors existing BOLT 12 invoice-signing-pubkey validation into a reusable helperAdds public API to bind an invoice signing key to an offer recipientAdds unit tests for issuer-id vs. path-last-hop matching behavior
This commit is a feature enhancement for LDK's internal serialization macros. It allows developers to mark old protocol fields as 'retired' (reserved but no longer used) in more places, so those type numbers cannot be accidentally reused. …
TLV type-number reservation mechanism extended to more macro-generated code pathsPrevents accidental reuse of retired protocol field type numbersAvoids UnknownRequiredFeature decode failures for obsolete even-type fields
This commit is a test-only cleanup in the Lightning Dev Kit (LDK) Rust codebase. It removes low-level byte-level tests for splice failure events and replaces them with a single cross-version test that actually loads a 0.2 node with seriali…
Cross-version serialization compatibility test addedRemoval of byte-level tests that could not detect real 0.2 mismatchesNo production code changes
This commit only adds a code comment explaining an existing quirk: if a revoked old channel transaction contains two identical-looking payment forwards and the other side claims both, the software may only claim one upstream while letting …
Behavioral quirk in revoked-commitment HTLC resolution documentedDuplicate (payment_hash, amount) HTLCs can map to the same upstream sourcePotential missed upstream preimage claim on second identical HTLC
This commit fixes a state-handling bug in Lightning Dev Kit's splicing feature. When a user tries to speed up or replace a pending splice (an 'RBF' attempt) and the older splice transaction unexpectedly gets confirmed on-chain, the softwar…
State-conflict handling between confirmed splice candidate and active RBF negotiationStructured abort propagation through chain-event pathConditional abort based on holder signature progress to avoid unsafe cancellation
Expand any commit for its author, full message, clarity score, changed files, triage signals, analysis, and source link.
AI review queuedFix underflow in blinded path amt_to_forwardby Valentine Wallace · e560ec17 · Jun 15, 2026 · 1 fileMessage 80 · StrongHigh 70Details
Commit message · Valentine Wallace
Fix underflow in blinded path amt_to_forward
If we have a high (200%+) proportional fee as an intermediate blinded node combined with a low inbound amount, we previously had some code that calculated the outbound amount of the forward that would've underflowed. This would've caused a panic in debug builds and caused us to relay a payment that should've been rejected (due to being unable to cover our high fee) in release builds.
Reported by Project Loupe.
80/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
Why it was queued
second-pass: broader security terminology
AI analysis · High 70/100
This commit fixes a subtraction underflow bug in the code that decides how much of a Lightning payment a blinded intermediate node should forward. With extremely high proportional fees and a small incoming payment amount, the code subtracted a larger fee from a smaller amount, which would crash in debug builds and silently produce a wrong, too-small result in release builds. In release builds that wrong result could have allowed a payment to be relayed that should have been rejected because it could not cover the node's fee. The fix uses Rust's checked subtraction so the function returns 'None' instead of underflowing.
Previously, we would spuriously allow fake scids that had a vout with the high byte set to pass our is_valid_{phantom,intercept,etc}_scid checks, even though our fake vouts only ever set the lowest 3 bits of the 2-byte vout.
This can't really be exploited since HTLCs that pass this check would still fail later on in the pipeline, and attackers that want to craft fake scids to pass our checks can still do so after this fix, either via brute force or by reusing a valid fake scid from a previously issued invoice. But at least this makes it harder for them to do so, and makes the check more correct than it was before. Plus invalid fake crafted scids like this could theoretically cause us to generate a spurious HTLCIntercepted event, which wouldn't be ideal.
Reported by Project Loupe.
80/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context
Why it was queued
explicit security language
AI analysis · Low 32/100
This commit fixes a validation bug in how Lightning Dev Kit checks 'fake' short channel IDs (SCIDs) used for routing tricks like phantom and intercept payments. The old check compared only the lowest byte of the vout field, so an attacker could set the high byte of the vout and still pass validation. The fix now compares the full 16-bit vout value. The project says this is not directly exploitable for stealing funds, but it could cause a spurious internal event and makes the validation more correct.
AI review queuedClear duplicate monitor-pending RAA on signer resendby Wilmer Paulino · 27223fdd · Jun 15, 2026 · 2 filesMessage 83 · StrongModerate 66Details
Commit message · Wilmer Paulino
Clear duplicate monitor-pending RAA on signer resend
The `chanmon_consistency` fuzz target found a reconnect ordering where `signer_pending_revoke_and_ack` and `monitor_pending_revoke_and_ack` could both describe the same owed `revoke_and_ack`.
The channel first received a `commitment_signed` whose monitor update completed, but the signer could not provide the next point or secret, leaving `signer_pending_revoke_and_ack` set. Later, receiving the peer `revoke_and_ack` freed holding-cell HTLCs and produced a held monitor update. While that monitor update was still blocked, `channel_reestablish` saw the peer one state behind and recorded `monitor_pending_revoke_and_ack`, plus the corresponding monitor-pending `commitment_signed`, so the messages could be replayed once monitor updating was restored.
If the signer unblocked before the held monitor update was released, `signer_maybe_unblocked` generated and sent the already monitor-safe RAA using `signer_pending_revoke_and_ack`. The monitor-pending flag was not cleared at that point, so `monitor_updating_restored` later generated the same RAA again when the held update completed. The peer had already advanced after accepting the signer-unblocked RAA, so it rejected the duplicate secret as not corresponding to its current pubkey and force-closed.
Fix this by clearing `monitor_pending_revoke_and_ack` in the signer-resume path only once a signer-pending RAA is actually being returned.
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidencesigning or wallet pathsecond-pass: security-sensitive path
AI analysis · Moderate 66/100
This commit fixes a bug in the Lightning Dev Kit where, after a peer reconnects, the same cryptographic 'revoke_and_ack' message could be generated and sent twice. The duplicate would contain a secret the peer had already accepted, so the peer would reject it and force-close the payment channel. The fix clears an internal 'monitor-pending' flag when the signer-resume path actually produces the message, preventing the later duplicate.
Lower-priority(Actually) remove incorrect `*mut` cast in net-tokioby Matt Corallo · b48dfa08 · Jun 15, 2026 · 1 fileMessage 73 · AdequateModerate 59Details
Commit message · Matt Corallo
(Actually) remove incorrect `*mut` cast in net-tokio
In ae62fa377a0a139d937ce2c7d87d3eb1612732af we removed an incorrect `&mut`, but failed to actually resolve the mut aliasing bug - there remained a deref of a `*mut` which is similarly invalid. Here we actually fix the bug and also DRY up code marginally.
Reported by Project Loupe.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 59/100
This commit fixes a Rust unsafe-code bug in the lightning-net-tokio networking module. The previous patch removed an `&mut` reference but left a `*mut` pointer dereference that still created aliasing mutable access to the same memory, which is undefined behavior in Rust. The fix removes the duplicate unsafe dereference and reuses an existing safe helper function instead. The bug was reported by Project Loupe, an external security research group.
Lower-priorityFix `Borrow`/`Hash` inconsistency on `Payment*` typesby Matt Corallo · a1ad1a30 · Jun 15, 2026 · 3 filesMessage 85 · StrongModerate 63Details
Commit message · Matt Corallo
Fix `Borrow`/`Hash` inconsistency on `Payment*` types
`Borrow`'d values are required to `Hash` identically to the original object so that a `Borrow`ed key can be used in place of an owned one in a `HashMap` lookup.
We'd violated this on our `Payment*` types, which we fix here. Note that changing the `Hash` implementation is generally not considered an API-breaking change and this seems like a useful fix.
Reported by Project Loupe.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Moderate 63/100
This commit fixes a Rust programming contract violation in several Lightning payment identifier types. In Rust, if a type can be 'borrowed' as a byte slice and used as a HashMap key, the borrowed form and the owned form must produce the same hash value. The old code used the type's automatic derived hash (which hashed the whole struct, including wrapper metadata) while borrowing only the inner byte array, so a borrowed key and an owned key could hash differently. That breaks HashMap lookups: you might store a value under one key and then be unable to find it with a borrowed version of the same key. The patch replaces the derived Hash implementation with one that hashes only the borrowed byte slice, restoring consistency. The commit message notes the issue was reported by Project Loupe.
Now that the payer nonce is included in the payer metadata of InvoiceRequest and Refund, Bolt12Invoice verification no longer needs the nonce from the blinded path's OffersContext. Remove it from OffersContext::OutboundPaymentForOffer and OffersContext::OutboundPaymentForRefund, along with enqueue_invoice_request's nonce parameter, which only existed to supply it. The nonce in RetryableInvoiceRequest is no longer used either but is still persisted -- and retained when reading state written by prior versions -- so that such versions can retry the payment and verify the resulting invoice after a downgrade.
The payment_id is kept in both variants, however. While no longer needed to confirm the invoice is for an invoice request or refund we created, it is checked against the payment id recovered from a received Bolt12Invoice's payer metadata to ensure the invoice arrived over the blinded path created for that payment. This prevents an attacker from reusing the blinded path of one of our payments to deliver another payment's invoice and correlate the two as ours.
Co-Authored-By: Claude <noreply@anthropic.com>
90/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification
This commit removes an old cryptographic nonce from the data carried inside Lightning "blinded paths" used when sending BOLT 12 offers and refunds. The nonce is no longer needed because a newer "payer metadata" field already carries the same secret. The commit keeps the payment ID in the blinded path and uses it to make sure an incoming invoice really belongs to the payment it claims to belong to. That prevents an attacker who captures one blinded path from delivering a different payment's invoice over it, which could otherwise link two of the user's payments together. The change is mostly a cleanup, but it also tightens the matching logic slightly.
Lower-priorityRemove unnecessary (and incorrect) `&mut` cast in net-tokioby Matt Corallo · ae62fa37 · Jun 15, 2026 · 1 fileMessage 73 · AdequateLow 33Details
Commit message · Matt Corallo
Remove unnecessary (and incorrect) `&mut` cast in net-tokio
The owned `Waker` wake method assumed it had the only reference to the sender as the `Waker` is owned at that point, however our `Waker`s can be `clone`d, leaving multiple references to the inner `Sender` (held in an `Arc`).
Thus, the `&mut` cast is technically undefined behavior. However, as this patch demonstrates, its only use is in calling an `&self` method which derefs an internal `Arc` in tokio, so its highly unlikely to lead to miscompilation.
Reported by Project Loupe.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 33/100
This commit fixes a Rust unsafe-code bug in the networking glue between the Lightning Dev Kit and Tokio. The code was treating a shared sender object as if it had exclusive access, which is undefined behavior in Rust. In practice the called method only reads through an internal reference counter, so the risk of real-world harm is low, but the pattern was incorrect and could theoretically confuse the compiler into generating wrong code.
Lower-priorityfuzz: model chanmon mempool miningby Joost Jager · 5c83835b · Jun 15, 2026 · 1 fileMessage 78 · AdequateInformational 13Details
Commit message · Joost Jager
fuzz: model chanmon mempool mining
Route chanmon broadcasts through an explicit harness mempool so relay, mining, wallet updates, and chain delivery share one path. This lets broadcast transactions enter the mempool before a modeled block confirms them.
On restart, sync loaded monitors and managers from their own persisted best blocks so raw monitors catch up without rewinding ChannelManager state. Cap modeled mining before unresolved HTLC timeout deadlines and use the LDK anti-reorg depth for setup confirmations.
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Informational 13/100
This commit is a test-only change to the Lightning Dev Kit fuzzing harness. It improves how the fuzzer simulates Bitcoin transaction relay, mempool behavior, block mining, and node restart synchronization. It does not change production code, user-facing APIs, or real network behavior, so it does not introduce a security vulnerability in the shipped library.
Lower-priorityReport the sending peer in Event::OnionMessageInterceptedby Jeffrey Czyz · 1a0e5304 · Jun 12, 2026 · 4 filesMessage 85 · StrongInformational 20Details
Commit message · Jeffrey Czyz
Report the sending peer in Event::OnionMessageIntercepted
When the OnionMessenger intercepts an onion message to forward, it now reports which peer sent us the message via a new `prev_hop` field, so handlers can apply source-based policy when deciding whether to forward.
`prev_hop` is `None` when the forward is enqueued by a message handler (the BOLT 12 static-invoice-server flow), which isn't given the sending node; otherwise it is the node we received the message from.
Co-Authored-By: Claude <noreply@anthropic.com>
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Informational 20/100
This commit adds a new prev_hop field to an existing event type so that applications using the Lightning Dev Kit can see which peer sent an intercepted onion message. It is a feature enhancement that improves policy control; it does not by itself fix a vulnerability or introduce a clear security bug.
Lower-priorityIntercept onion messages for unknown SCID hopsby Elias Rohrer · 2e7cc44c · Jun 12, 2026 · 6 filesMessage 68 · AdequateLow 37Details
Commit message · Elias Rohrer
Intercept onion messages for unknown SCID hops
Allow integrations to intercept blinded onion-message hops that identify the next node by short channel id, so LSPS-style protocols can resolve those hops out of band instead of dropping the message.
Co-Authored-By: HAL 9000
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 37/100
This commit adds a new optional feature to LDK's onion message forwarding. Previously, if an onion message's next hop was identified by a short channel ID (SCID) that the node didn't know, the message was silently dropped. Now, if a user explicitly enables 'intercept_for_unknown_scids', the node can hold onto the message and emit an event, allowing external protocols (like LSPS-style services) to resolve the SCID out-of-band and forward the message later. The change also updates how these intercepted events are serialized for backwards compatibility with older LDK versions.
InvoiceRequest and Refund have payer metadata consisting of an encrypted payment id and, originally, a nonce used to derive the payer signing keys and authenticate any corresponding invoices. The nonce was elided to save space once it was included in the OffersContext of blinded reply paths, but that means verifying a Bolt12Invoice requires state outside the invoice itself. Upcoming payment proofs (#4297) need the invoice signing keys derivable from the invoice request alone, so include the nonce in the payer metadata again and verify invoices using it rather than the context's nonce.
This breaks verification of invoices for invoice requests and refunds with blinded paths created by prior versions, as their payer metadata lacks the nonce; such payments will fail and must be retried with a new payment id. Refunds without blinded paths are unaffected, as their metadata always included the nonce.
Co-Authored-By: Claude <noreply@anthropic.com>
86/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
Why it was queued
signing boundarydefensive validationsigning or wallet path
AI analysis · Low 33/100
This commit changes how BOLT12 invoices are verified in the Lightning Dev Kit. Previously, some invoices could be verified using a nonce stored in the blinded reply path context. Now, the nonce is always included inside the encrypted payer metadata carried by the invoice request or refund. This makes invoices self-contained and prepares the code for future payment proofs. It is a protocol-correctness and forward-compatibility change, not a fix for an active exploit. Old invoice requests/refunds with blinded paths created before this change will fail verification and must be retried with a new payment id.
Lower-priorityf - Prevent stale fs-store writesby Elias Rohrer · 2c09a261 · Jun 11, 2026 · 1 fileMessage 78 · AdequateModerate 56Details
Commit message · Elias Rohrer
f - Prevent stale fs-store writes
Exercise the stale-write race through the stored filesystem bytes so the regression test covers the user-visible overwrite bug.
Co-Authored-By: HAL 9000
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Moderate 56/100
This commit is a follow-up ('f') that strengthens a regression test for a filesystem persistence bug in rust-lightning. The bug being tested is a race condition where an older, delayed write could overwrite a newer write after a lock was cleaned up, potentially causing stale data to be stored. The commit itself only changes test code and test-only hooks; it does not change the production fix. It makes the test verify the actual saved file contents rather than just internal version numbers, so the test now covers the user-visible overwrite problem.
Lower-priorityf - Prevent stale fs-store writesby Elias Rohrer · 7106181a · Jun 11, 2026 · 1 fileMessage 68 · AdequateLow 42Details
Commit message · Elias Rohrer
f - Prevent stale fs-store writes
Move the version-allocation ordering note to the allocation it describes so the cleanup invariant is easier to follow.
Co-Authored-By: HAL 9000
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 42/100
This is a small follow-up patch (marked with 'f -') that reorders code and adds a comment in a filesystem persistence module. The change moves version allocation to happen while a lock-map mutex is still held, preventing a theoretical race where a cleanup routine could remove a lock entry after a version number is reserved but before the lock reference is copied. The commit message frames this as preventing 'stale fs-store writes.' The actual code behavior change is minimal and the patch is conservative.
Lower-priorityAdd fees value for recent paymentsby Alexander Shevtsov · af19ed5f · Jun 10, 2026 · 3 filesMessage 68 · AdequateInformational 15Details
Commit message · Alexander Shevtsov
Add fees value for recent payments
Introduce fields `pending_fee_msat` for `RecentPaymentDetails::Pending` and `fee_paid_msat` for `RecentPaymentDetails::Fulfilled`.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100
This commit adds optional fee fields to LDK's recent-payment tracking structures so users can see routing fees for pending and completed payments. It is a straightforward feature/data exposure change with no security-relevant behavior visible in the diff.
Lower-priorityPrevent stale fs-store writes after lock cleanupby Elias Rohrer · 7b36bc8b · Jun 10, 2026 · 1 fileMessage 78 · AdequateModerate 59Details
Commit message · Elias Rohrer
Prevent stale fs-store writes after lock cleanup
Reserve write versions while holding the per-path lock map mutex so cleanup cannot remove the version state between version allocation and lock reference acquisition.
Add a regression test for the ordering invariant.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Moderate 59/100
This patch fixes a subtle race condition in rust-lightning's file-system persistence layer. Previously, the code could reserve a new write version number before it had safely grabbed the corresponding per-file lock. A background cleanup task could then delete the lock entry in between, leaving the version number associated with a lock that no longer exists. The fix grabs the lock map first, then reserves the version while still holding that map lock, and adds a regression test to prove the ordering is correct.
Lower-priorityRelease LSPS2 intercepted HTLCs on open failureby Elias Rohrer · 6b75e5a4 · Jun 10, 2026 · 2 filesMessage 68 · AdequateModerate 60Details
Commit message · Elias Rohrer
Release LSPS2 intercepted HTLCs on open failure
When a JIT channel open fails, release queued intercepted HTLCs through the intercept API so they are not held until expiry. Keep resetting the LSPS2 state if an intercept has already been released.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 60/100
This commit fixes a bug in the Lightning Dev Kit's LSPS2 (JIT channel) service. When a just-in-time (JIT) channel opening failed, intercepted HTLCs (pending payments held for that channel) were not being released back through the intercept API. They could sit until their expiry timeout, tying up funds and potentially causing payment failures or liquidity problems. The fix releases those held payments immediately when the channel open fails, and also handles the case where an intercept was already released by resetting the LSPS2 state anyway.
When a used async receive offer's refreshed static invoice is persisted, advance the recorded invoice creation time. This keeps the refresh threshold anchored to the newest invoice instead of making the offer look stale on every timer tick.
Add coverage that a used offer does not enqueue another ServeStaticInvoice immediately after the server confirms the refresh.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
AI analysis · Low 37/100
This commit fixes a bug where a Lightning node's timer would keep refreshing and re-sending the same static invoice over and over, instead of waiting for the proper refresh interval. The root cause was using the older (minimum) invoice creation time rather than the newest (maximum) one when deciding if an offer looked stale. This could waste bandwidth, create unnecessary network messages, and potentially cause the node to look unreliable or spammy to peers.
Lower-priorityAccount for UTXO base weight in anchor reserve checksby Elias Rohrer · 5e7b7d3d · Jun 10, 2026 · 1 fileMessage 73 · AdequateLow 44Details
Commit message · Elias Rohrer
Account for UTXO base weight in anchor reserve checks
get_supportable_anchor_channels estimates how much each reserve UTXO can contribute after spending fees. Include the base input weight in that fee so UTXOs just below the public per-channel reserve are not counted as supporting another anchor channel.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 44/100
This commit fixes a calculation in how Lightning Dev Kit estimates whether leftover on-chain funds (UTXOs) are enough to support opening additional 'anchor' channels. Previously, the code only subtracted the fee for the cryptographic proof needed to spend a UTXO, but forgot to also subtract the fixed base size every transaction input adds. As a result, a UTXO worth just slightly less than the advertised reserve could be wrongly counted as sufficient, potentially leading the node to believe it could open more anchor channels than it actually could afford to fund later. The fix adds that base input weight to the fee estimate, and a new test confirms a borderline UTXO is now rejected.
Security candidateReturn P2WSH script pubkey for keyed anchor prevoutsby Elias Rohrer · ccf45e4f · Jun 10, 2026 · 1 fileMessage 73 · AdequateLow 44Details
Commit message · Elias Rohrer
Return P2WSH script pubkey for keyed anchor prevouts
AnchorDescriptor::previous_utxo is used for coin selection and PSBT witness_utxo metadata. For keyed anchors it should describe the on-chain P2WSH anchor output instead of the witness script so wallets can validate and sign the package.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarydefensive validationsigning or wallet path
AI analysis · Low 44/100
This commit fixes a bug in how Lightning Dev Kit describes anchor outputs when preparing transactions for external wallets to sign. Previously, for a type of anchor tied to a specific channel key, the code returned the raw 'witness script' (the spending conditions) instead of the proper P2WSH address/script pubkey. Wallets use this data to identify and validate the coin being spent. Providing the wrong descriptor could cause wallets to reject the PSBT or, in worst cases, misidentify the output, potentially leading to invalid transactions or unsafe signing behavior. The fix converts the redeemscript to its P2WSH script pubkey, and adds a regression test.
Lower-priorityThrottle LSPS5 lifecycle cooldown resetsby Elias Rohrer · c6099a8a · Jun 10, 2026 · 3 filesMessage 80 · StrongModerate 68Details
Commit message · Elias Rohrer
Throttle LSPS5 lifecycle cooldown resets
LSPS5 resets notification cooldowns when a peer reconnects so clients can receive prompt wake-ups after coming online. A peer can otherwise churn connections to clear the webhook cooldown repeatedly, turning the LSP into an amplification source for registered notification URLs.
Rate-limit how often peer lifecycle events may clear notification cooldowns while keeping the first reset immediate. Also make LSPSDateTime elapsed-time calculation directional so backwards clock movement does not make future timestamps look expired.
Co-Authored-By: HAL 9000
This finding was discovered by Project Loupe
80/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Moderate 68/100
This patch fixes a denial-of-service/amplification weakness in the LSPS5 webhook service of rust-lightning. Previously, every time a peer connected or disconnected, the LSP would immediately clear the one-minute 'cooldown' that prevents repeated webhook notifications. A malicious or misbehaving peer could repeatedly connect and disconnect to force the LSP to send many webhook requests to registered URLs, effectively using the LSP as an amplifier against third-party servers. The patch now allows only one cooldown reset every 10 seconds per peer. It also fixes a related time-calculation bug so that a clock moving backward does not incorrectly make future timestamps look expired.
Lower-priorityClear stale monitor pending resends on reestablishby Wilmer Paulino · c58cba3a · Jun 9, 2026 · 3 filesMessage 73 · AdequateModerate 66Details
Commit message · Wilmer Paulino
Clear stale monitor pending resends on reestablish
A stale ChannelManager can be reloaded after a monitor update has already completed in a prior runtime and released its post-update messages to the counterparty. The latest ChannelMonitor is not stale, but the serialized manager may still contain the old in-flight monitor state and `monitor_pending_*` resend flags from before the completion action ran.
This becomes observable when startup monitor-completion background events are interleaved with splice promotion. On reload, the completed monitor update is queued as a background event. If a splice confirmation is processed before that background event fully resumes the channel, splice promotion can create a new `RenegotiatedFundingLocked` monitor update. The old completion is then blocked behind the new in-flight splice update. Once the channel reconnects and the splice update completes, `monitor_updating_restored` may consume the stale `monitor_pending_revoke_and_ack` / `monitor_pending_commitment_signed` flags and release a duplicate `revoke_and_ack` or `commitment_signed`.
The peer's `channel_reestablish` commitment numbers are authoritative for this case. If `next_remote_commitment_number` says the peer is not waiting for a `revoke_and_ack`, clear `monitor_pending_revoke_and_ack`. Likewise, if `next_local_commitment_number` says the peer already has our latest `commitment_signed`, clear `monitor_pending_commitment_signed`.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 66/100
This patch fixes a bug in the Lightning Dev Kit where a node could accidentally resend old cryptographic messages to a peer after restarting. When a stale saved channel state was reloaded, the node might think it still owed the peer a 'revoke_and_ack' or 'commitment_signed' message that had already been sent. During channel reestablishment, the peer's commitment numbers now authoritatively clear these stale flags, preventing duplicate messages that could confuse or disrupt the channel.
Lower-prioritySend splice_locked before reestablish commitmentby Wilmer Paulino · f0c4af91 · Jun 9, 2026 · 2 filesMessage 68 · AdequateLow 46Details
Commit message · Wilmer Paulino
Send splice_locked before reestablish commitment
If we have pending updates to send to our counterparty on reestablishment, while also pending a `splice_locked` send, then we must send our `splice_locked` first as the pending updates are considering the post-splice-locked state.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 46/100
This commit fixes the order in which a Lightning node resends messages after reconnecting to a peer during a channel splice. Previously, if the node had both a pending 'splice_locked' message and pending commitment updates to retransmit, it could send the commitment updates first. Because those updates assume the splice has already been locked in, sending them before 'splice_locked' could confuse the peer and disrupt channel state synchronization. The fix moves 'splice_locked' ahead of commitment retransmission, and adds tests to verify the correct ordering.
Lower-priorityRaise iteration capacity in chanmon consistency when settling stateby Wilmer Paulino · 099bb09e · Jun 9, 2026 · 1 fileMessage 83 · StrongInformational 13Details
Commit message · Wilmer Paulino
Raise iteration capacity in chanmon consistency when settling state
LDK and the chanmon_consistency fuzz target have grown in complexity recently and thus require more iterations than previously assumed to fully settle the state of all active channels.
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Informational 13/100
This commit only changes an internal fuzz-testing harness (a tool used to find bugs during development, not production code). It raises the maximum number of loop iterations allowed while waiting for simulated channel state to settle, and fixes a typo in a panic message. There is no change to the actual Lightning protocol logic or any user-facing software.
Now that the fuzz target supports canceling splice funding attempts, we may see failed signing attempts due to the cancellation.
90/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification
Why it was queued
signing boundaryfuzzing or regression evidence
AI analysis · Informational 16/100
This commit changes a fuzz test (a randomized testing harness) so it no longer crashes when a simulated splice-funding signing event becomes stale. The change only affects test code, not the production Lightning library, and it ignores an expected error rather than fixing a runtime security bug.
Lower-prioritySend splice_locked for promoted splice on reconnectby Wilmer Paulino · 294fbbae · Jun 9, 2026 · 2 filesMessage 73 · AdequateModerate 53Details
Commit message · Wilmer Paulino
Send splice_locked for promoted splice on reconnect
When a splice confirms after our `channel_reestablish` was generated and sent, but prior to processing the counterparty's, we may promote the splice and clear `pending_splice`. In such cases, we're still required to send an explicit `splice_locked` as the `channel_reestablish` we sent did not consider the splice confirmation.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 53/100
This commit fixes a protocol edge case in Lightning splicing. If a splice transaction confirmed at just the wrong moment—after one peer sent a channel-reestablish message but before it received the other peer's—the node could promote the new splice funding state internally but forget to send the required follow-up 'splice_locked' message. Without that message, the counterparty would not know the splice was active on this side, potentially leaving the channel in an inconsistent or stuck state. The fix adds a fallback that sends splice_locked in that reconnect scenario, plus a regression test.