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 changes how the Lightning networking code handles oversized encrypted messages. Previously, certain conditions would cause the program to crash with a panic. Now the code returns errors instead, which is a defensive improvement…
panic-to-error conversion for oversized message encryption/decryptiondenial-of-service hardening against oversized peer messagesdebug_assert retained to preserve test coverage of invariant violations
This commit simply updates the 'repository' web links in 15 package metadata files from GitHub to a self-hosted Forgejo instance. It does not change any program code, build logic, dependencies, or security behavior. There is no security is…
This commit fixes a bug in the Lightning Dev Kit where, after a disconnection, a node could fail to retransmit a 'splice_locked' message to a peer that was still waiting for transaction signatures. Without this retransmission, the two peer…
Protocol state desynchronization between channel peers after reconnectionMissing retransmission of splice_locked for 0-conf splice channelsPotential channel unusability or stuck splice negotiation
This commit fixes a small accounting bug in how the Lightning wallet estimates the size (and therefore transaction fee) of a special Bitcoin transaction that sweeps funds back to the user after a channel closes. The old code always assumed…
debug assertion failure possible in development/testing buildstransaction weight/fee estimate overestimation up to 3 WUconstant replaced with per-descriptor length computation
This commit changes the project's internal code-review workflow. It stops automatically assigning a human reviewer when a pull request is opened; instead, contributors must manually click a button to request a reviewer after first addressi…
This commit fixes a bug in LDK's Lightning channel reconnection logic after a splice (a way to resize a channel's on-chain funds). If one peer had already received the splice signatures but the other had not, and then they disconnected and…
Protocol-state inconsistency on reconnection after splice signature exchangePotential channel stall/force-close due to quiescence not being exited before commitment updateFuzzer-discovered edge case in Lightning splicing retransmission
This commit adds a new option for Lightning invoice creators to explicitly tell payers not to use multi-path payments (MPP) when paying an invoice. It does not change any enforcement rules; it only changes what feature bits are advertised …
New API surface for feature advertisement controlExplicit documentation that the method does not enforce single-HTLC receipt, shifting enforcement responsibility to callersNo removal or weakening of existing validation logic
This commit adjusts the project's continuous integration (CI) test script to pin an older version of a build-time helper crate called `jobserver` when using older Rust compilers. It is a build compatibility fix, not a security patch, and d…
This commit only adds new test code. It exercises how a newer version of LDK exchanges saved channel data with the older LDK 0.2 release when a channel has a pending splice. There is no change to production logic, no bug fix, and no securi…
This commit removes the 'Option' wrapper from several HTLC amount fields, making them required instead of optional. It is a cleanup/refactoring change that simplifies the code by assuming the amount is always known. The commit message fram…
Removal of Option wrapper for financial amount fieldsSerialization format change from optional to required TLV fieldsLoss of backward compatibility with older serialized monitor/channel state
This commit is a code cleanup inside the project's test suite. It replaces a helper function with several hard-to-read positional arguments (like bare `false` and `None`) with a 'builder' pattern that names each option. This makes the test…
This commit is a feature addition, not a vulnerability fix. It extends rust-lightning's BOLT 12 payment support so that when a wallet pays a BOLT 12 invoice, the paid invoice is saved through retries and restarts and is later exposed in th…
New BOLT 12 payer proof feature: persists paid invoice across retries/restarts and exposes it in Event::PaymentSentPayer signing key re-derived from invoice payer metadata rather than storing extra key materialAdds end-to-end test for proof creation, verification, and bech32 round-trip
This commit is a code cleanup (refactor) in the Lightning Dev Kit library. It moves existing payer key-derivation logic into shared helper functions so that future 'payer proof' features can reuse the same code. The change does not appear …
Refactor only: moves existing key derivation/verification logic into helpers without changing algorithmsAdds new public API `Bolt12Invoice::derive_payer_signing_keys` for payer proof key recoveryNo mention of vulnerability, bug, CVE, security fix, or exploit in commit title/message
This commit changes a CI workflow for the rust-lightning project. It stops trying to push new fuzz test inputs directly to a corpus repository from automated test runs, and instead uploads them as a temporary artifact that a separate sched…
This commit adds partial support in the Lightning Dev Kit node software for receiving and temporarily holding multi-part trampoline payments, then deliberately rejects them once all parts arrive because full outbound forwarding is not yet …
New trampoline forward handling path accumulates MPP parts before rejectingDebug assertion guards first-HTLC failure in MPP mergeTODO comment flags possible MPP inconsistency in next_node_id across trampoline parts
This commit removes a redundant 32-byte shared secret field from an internal data structure used when forwarding trampoline payments in the Lightning Dev Kit. The developers realized the secret was already stored inside each previous hop's…
Removes redundant secret field from in-memory/persisted stateChanges TLV serialization layout for HTLCSource::TrampolineForwardBreaking persistence change acknowledged by commit author
This commit changes the project's automated reviewer-assignment workflow to stop using a long-lived secret token and instead request a short-lived authentication token from the Forgejo CI service. This is a security-hardening improvement: …
Removal of long-lived repository secret from CI workflowAdoption of OIDC-based short-lived token for API authorizationWorkflow runs in pull_request_target context with no code checkout
This commit only adds new fuzz-testing commands to an existing test harness. It lets the fuzzer temporarily block and then re-enable the local node's own signing operations during simulated channel failures. There is no change to productio…
This commit hardens the project's automated build and test scripts by replacing loose version tags like 'actions/checkout@v4' with exact commit hashes served from a specific domain. This prevents a compromised or renamed third-party action…
CI/CD supply-chain hardeningAction reference pinning to immutable commit hashUse of explicit action mirror URL
This commit fixes a logic bug in the Lightning Dev Kit's channel splicing code. Previously, the code wrongly assumed that no unrelated monitor update could be pending when a splice `tx_signatures` message arrived while the channel was quie…
Assertion relaxation in state-machine handling of splice `tx_signatures`Race condition between unrelated HTLC preimage monitor update and splice signature exchangePotential panic or protocol stall due to overly strict debug assertion
Ignore stale announcement_signatures instead of force-closing
A peer may transmit `announcement_signatures` signed over a stale `short_channel_id` — most plausibly a retransmission or a peer implementation whose view hasn't caught up to our post-splice promotion. Verifying such sigs against the current `UnsignedChannelAnnouncement` (built from `self.funding`) always fails the hash check, which previously produced a force-close.
BOLT #7 does not require closing in this situation; the mismatch is expected across splice handoffs. Short-circuit with `ChannelError::Ignore` when `msg.short_channel_id` doesn't match the current funding's scid, leaving the genuine invalid-signature paths in place for sigs that actually target our current scid.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Links an issue, advisory, or supporting reference✓ Names security-relevant behavior explicitly
Why it was queued
signing boundary
AI analysis · Moderate 62/100
This change fixes a bug where a Lightning node would unnecessarily force-close a payment channel if its peer sent an outdated 'announcement_signatures' message referencing the old channel identifier after a splice (a channel funding update). The node now simply ignores these stale messages, keeping the channel open. The bug was not a direct theft of funds, but it could cause unwanted channel closures and disruption.
Skip pre-splice announcement_signatures on reestablish
When a splice transaction confirms on both sides while peers are disconnected, each peer's `channel_reestablish` carries `my_current_funding_locked` with the splice txid. In the reestablish handler, `get_announcement_sigs` was called before the inferred `splice_locked` was processed and the splice was promoted, so `self.funding` still pointed to the pre-splice scope. If `announcement_sigs_state` was `NotSent`, the generated `announcement_signatures` carried the pre-splice `short_channel_id` and bitcoin key — which the peer (having already promoted via its own inferred `splice_locked`) would verify against the post-splice `UnsignedChannelAnnouncement`, failing the signature check and force-closing.
Skip the pre-promotion call when `my_current_funding_locked` matches the splice we've already confirmed — i.e. `pending_splice.sent_funding_txid` is set and equals the peer's locked txid. `maybe_promote_splice_funding` emits correct post-splice signatures after the inferred `splice_locked` is processed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Names security-relevant behavior explicitly
Why it was queued
signing boundary
AI analysis · Moderate 57/100
This commit fixes a bug in the Lightning Dev Kit where reconnecting after a channel 'splice' (a funding update) could cause one peer to send outdated channel announcement signatures. The peer receiving those stale signatures would reject them and force-close the channel. The fix skips generating announcement signatures until the splice has been promoted to the new funding, so both sides agree on the current channel state.
Several code paths exit quiescence by calling `clear_quiescent()` directly without also clearing the disconnect timer via `mark_response_received()`. This causes the timer to fire after the splice completes or is aborted, spuriously disconnecting the peer.
Replace `clear_quiescent()` with `exit_quiescence()` in `on_tx_signatures_exchange`, `reset_pending_splice_state`, and `peer_connected_get_handshake`, which clears both the quiescent state and the disconnect timer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundary
AI analysis · Low 44/100
This commit fixes a bug in the Lightning Dev Kit where a timer meant to disconnect unresponsive peers could fire by mistake after a splice operation completed, was aborted, or after reconnecting. The fix makes sure the timer is cleared whenever the protocol leaves its 'quiet' (quiescent) state, preventing unnecessary peer disconnections.
Move shared fuzz logic into the root fuzz crate and generate fake-hashes and real-hashes runner crates.
Keep `chanmon_consistency_target` on the real-hashes side, remove the fuzz-local Cargo config, and update scripts, CI, coverage, and docs to use explicit flags for each runner.
Generate the hash-mode compile checks in the wrapper bins without a synthetic Cargo feature, while keeping the wrapper template close to its original shape.
AI tools were used in preparing this commit.
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 evidenceseed or entropy pathsigning or wallet pathboot or update pathauthentication pathparser or protocol path
AI analysis · Informational 15/100
This commit is a build-system and test-infrastructure refactor for the project's fuzzing (automated randomized testing) harness. It splits fuzz test runners into two groups based on whether they use fake or real cryptographic hashes, moves shared code into a common crate, and updates CI scripts, coverage tooling, and documentation accordingly. There is no change to the actual Lightning protocol library or to how production nodes behave, and no security vulnerability is introduced or fixed.
The build-sync job started resolving hyper-rustls v0.27.8 for the esplora-async-https configuration. That release requires rustc 1.85, but the sync CI job still runs on Rust 1.75.0.
Pin hyper-rustls to 0.27.7 when building with rustc older than 1.85, alongside the existing MSRV dependency pins in ci-tests-common.sh.
AI tools were used in preparing this commit.
90/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
access control
AI analysis · Informational 15/100
This is a routine CI maintenance commit. It pins an older version of a dependency (hyper-rustls) so that automated builds using an older Rust compiler (1.75) continue to work. It does not change application code, fix a vulnerability, or alter how the software behaves in production.
Security candidateUse `saturating_mul` when multiplying feerates by the fee spike bufby Matt Corallo · b98d7b8a · Apr 13, 2026 · 2 filesMessage 90 · StrongModerate 53Details
Commit message · Matt Corallo
Use `saturating_mul` when multiplying feerates by the fee spike buf
In theory a channel's feerate could be set to some absurd value (millions of satoshis per vB) and we'd overflow the fee spike buffer, accepting the absurd fee and ignoring our fee spike buffer check. This is harmless - the counterparty has much easier ways of bricking the channel if they want, and paying several BTC in fees is probably not the best way. Our commitment transaction and dust fee exposure logic all correctly map the `u32` to a `u64` before multiplying, making them overflow-safe.
Still, its good to fix overflows because it is a remotely-reachable crash in debug builds.
Reported by Jordan Mecom of Block's Security Team
90/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Names security-relevant behavior explicitly
Why it was queued
memory safetysigning or wallet path
AI analysis · Moderate 53/100
This patch fixes a potential integer overflow when calculating Lightning channel fees. If a malicious or misconfigured peer set an extremely high transaction fee rate, the software could overflow a 32-bit integer while applying a safety buffer multiplier. In release builds this would silently wrap around and ignore the safety buffer; in debug builds it would crash. The fix uses saturating multiplication so the result stays at the maximum safe value instead of overflowing. The commit notes this is not practically exploitable for theft because a peer already has easier ways to disrupt a channel, but it removes a remotely reachable debug crash.
The `PaymentConstraints::max_cltv_expiry` field exists to ensure a blinded path expires across the entire path at once - once the path is expired it will be rejected by the introduction node rather than traversing the entire path and failing at the destination.
This was broken by the fact that we were checking the outgoing CLTV value rather than the incoming one, which admittedly isn't clear in the spec but is somewhat implied. Here we fix this, updating a test which was actually (kinda) exploiting this privacy loss rather than allowing the HTLC to fail at the introduction node.
This, of course, does not risk funds loss as our own CLTV policy is still enforced on top. The only impact it could have is a recipient which was relying on blinded path expiry to avoid some cost (e.g. LSPS5 node wakeup cost) involved in receiving an HTLC they ultimately fail, though I'm not aware of any practical deployment where that is a concern.
Reported by Jordan Mecom of Block's Security Team
95/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification✓ Names security-relevant behavior explicitly
Why it was queued
explicit security language
AI analysis · Low 43/100
This commit fixes a bug in how Lightning Dev Kit checks expiry times for payments sent through 'blinded paths' (a privacy feature that hides the final recipient). The code was accidentally checking the outgoing expiry time instead of the incoming one. Because of this, a payment could travel deeper into the blinded path than intended before being rejected, slightly weakening the privacy/cost protection that blinded-path expiry is meant to provide. The commit explicitly states this does not risk loss of funds.
Security candidateRemove dead string search in fuzz SearchingOutputby Joost Jager · b9181c36 · Mar 30, 2026 · 1 fileMessage 83 · StrongInformational 15Details
Commit message · Joost Jager
Remove dead string search in fuzz SearchingOutput
The searched-for log message ("Outbound update_fee HTLC buffer overflow") no longer exists in the lightning crate, so the from_utf8 + contains check on every log line was pure waste.
AI tools were used in preparing this commit.
83/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Names security-relevant behavior explicitly
Why it was queued
memory safetyfuzzing or regression evidence
AI analysis · Informational 15/100
This commit is a cleanup of a fuzz-testing helper. It removes a wrapper that scanned every log line for a specific error message that no longer exists in the codebase. Because the searched message was already gone, the wrapper served no purpose and only wasted CPU. There is no change to production Lightning code, no user-facing behavior change, and no security fix.
Security candidateAdd 0-reserve to `accept_inbound_channel_from_trusted_peer`by Leo Nash · 954bf2df · Mar 26, 2026 · 11 filesMessage 65 · AdequateLow 34Details
Commit message · Leo Nash
Add 0-reserve to `accept_inbound_channel_from_trusted_peer`
This new flag sets 0-reserve for the channel opener.
65/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides an explanatory body
Why it was queued
signing or wallet pathboot or update path
AI analysis · Low 34/100
This commit renames and expands a special Lightning channel-acceptance API. Previously, users could manually accept an inbound channel from a trusted peer and treat it as confirmed immediately (zero-conf). Now the same API also allows setting the counterparty's required channel reserve to zero. A zero reserve means the peer can spend their entire balance and force-close the channel at no cost to themselves, which removes a key financial deterrent against cheating. The change is explicitly documented as dangerous and only appropriate for trusted peers, but it introduces a new risky option that did not exist before.
Security candidatePrevent downgrades in case holder-selected reserve is zero satoshisby Leo Nash · 63e4538e · Mar 26, 2026 · 1 fileMessage 73 · AdequateInformational 22Details
Commit message · Leo Nash
Prevent downgrades in case holder-selected reserve is zero satoshis
We prevent downgrades from 0.3 only in the case where the holder-selected reserve is 0, as we've had support for counterparty selected 0-reserves in prior releases.
There is no need for this sentinel in `FundingScope` serialization code as this would only apply to pending `FundingScope`'s.
Also, if the current scope has some zero-reserve, that reserve is carried over to all pending scopes automatically. Therefore it is not possible for a pending scope to have some 0-reserve without the current one also having it.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
update trust
AI analysis · Informational 22/100
This commit adds a marker to saved channel data so that older versions of the software will refuse to load it if the channel uses a zero-satoshi reserve chosen by the local user. That prevents accidental downgrades that could mishandle such channels, because older releases only understood zero-reserve channels when the remote side chose the zero reserve. It is a forward-compatibility guard, not a fix for an active attack.
Security candidateAdd inbound and outbound checks for zero reserve channelsby Leo Nash · 98b71c88 · Mar 25, 2026 · 7 filesMessage 77 · AdequateHigh 70Details
Commit message · Leo Nash
Add inbound and outbound checks for zero reserve channels
The goal is to prevent any commitments with no outputs, since these are not broadcastable.
77/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides an explanatory body✓ Explains rationale or failure mode
Why it was queued
signing or wallet pathboot or update path
AI analysis · High 70/100
This commit fixes a bug in the Lightning Dev Kit where a payment channel could end up with a commitment transaction that has zero spendable outputs. In Bitcoin, a transaction with no outputs is invalid and cannot be broadcast, which would make it impossible to enforce or recover funds from the channel if something goes wrong. The patch adds checks during channel opening, fee updates, and HTLC handling to ensure that zero-reserve channels always keep at least one valid output.
Security candidatefuzz: use process::exit panic hook in stdin_fuzz on macOSby Joost Jager · 39c8b0c8 · Mar 20, 2026 · 72 filesMessage 95 · StrongInformational 15Details
Commit message · Joost Jager
fuzz: use process::exit panic hook in stdin_fuzz on macOS
On macOS, panic=abort causes the process to call abort() which sends SIGABRT. The ReportCrash daemon then tries to generate a crash report, leaving the process stuck in an uninterruptible wait state that cannot be killed even with SIGKILL. This makes stdin_fuzz unusable for crash reproduction on macOS.
Install a custom panic hook (gated behind #[cfg(target_os = "macos")]) that flushes stdout (preserving log output), prints the panic info with a full backtrace to stderr, then calls process::exit(1) to terminate cleanly before the abort machinery runs. The hook is only installed on macOS to avoid interfering with debuggers like GDB on Linux.
AI tools were used in preparing this commit.
95/100 · StrongMessage clarity
✓ Specific, 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
fuzzing or regression evidencesigning or wallet pathboot or update pathauthentication pathparser or protocol path
AI analysis · Informational 15/100
This commit only changes internal fuzz-testing helper programs so they exit cleanly on macOS instead of getting stuck when a crash occurs. It does not affect the actual Lightning Dev Kit library, real Lightning nodes, or any user-facing code. There is no security vulnerability being fixed or introduced.
Release tx_signatures after async monitor update completes
In 83b2d3e, we reworked `ChannelManager::funding_transaction_signed` such that it would also for a user to cancel a splice up until they send `commitment_signed`. Previously, we would would only emit `Event::FundingTransactionReadyForSigning` when both nodes exchanged `commitment_signed` and the corresponding monitor update completed. With the event now being generated immediately after the nodes exchange `tx_complete`, we now need to handle the monitor update not having completed by the time we are ready to send `tx_signatures`. Unfortunately, we also did not have test coverage, allowing this to go unnoticed until being caught by the fuzzer due to a debug assertion. Doing so avoids a potential funds-loss scenario if the funding transaction confirms without the counterparty's signature for our commitment being durably persisted.
100/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification✓ Names security-relevant behavior explicitly
Why it was queued
signing boundaryfuzzing or regression evidencesigning or wallet path
AI analysis · Moderate 66/100
This commit fixes a bug in the Lightning Dev Kit where, during a special channel operation called splicing, the node could release its signatures for the new funding transaction before the local channel monitor had durably saved the counterparty's signature for the new commitment. If the funding transaction confirmed on-chain while the counterparty's signature was not yet persisted, the node could be left unable to enforce its funds, creating a potential loss of funds scenario. The fix delays sending `tx_signatures` until the asynchronous monitor update completes, and adds tests to cover this case.
Security candidateAdd test for monitor update after funding spendby Joost Jager · 1d3704d5 · Mar 19, 2026 · 1 fileMessage 78 · AdequateModerate 56Details
Commit message · Joost Jager
Add test for monitor update after funding spend
Add a regression test that reproduces the panic when a commitment_signed is processed after the counterparty commitment transaction has confirmed. The ChannelMonitor's no_further_updates_allowed() returns true, causing update_monitor to fail, which ChainMonitor overrides to InProgress. A subsequent preimage claim returning Completed then triggers the per-channel assertion that Completed must not follow InProgress.
AI tools were used in preparing this commit.
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 evidenceboot or update path
AI analysis · Moderate 56/100
This commit adds a regression test that reproduces a crash (panic) in the Lightning Dev Kit's channel monitoring logic. The crash happens when a blockchain event and a peer message arrive in an unlucky order: after the counterparty's commitment transaction confirms on-chain, the local node still processes a new commitment_signed message from that peer. The code marks the channel monitor as frozen, but a later legitimate payment preimage claim returns a success status, conflicting with the earlier frozen status and triggering an internal assertion that crashes the node.
Replace dual-sync-async persistence panic with Watch contract
Commit 0760f99 ("Disallow dual-sync-async persistence without restarting") added a panic in non-test builds when a Persist implementation returns both Completed and InProgress from the same ChannelManager instance. However, this check runs against the status that ChainMonitor returns to ChannelManager, not the raw Persist result. When ChannelMonitor::update_monitor fails (e.g. a counterparty commitment_signed arrives after a funding spend confirms), ChainMonitor persists the full monitor successfully but overrides the return value to InProgress. If the user's Persist impl only ever returns Completed, this override triggers a false mode-mismatch panic.
This replaces the panic with a per-channel contract at the Watch trait level: a Watch implementation must not return Completed for a channel update while prior InProgress updates are still pending. Switching from Completed to InProgress is always allowed, but switching back is impractical because the Watch implementation cannot observe when ChannelManager has finished processing a MonitorEvent::Completed. The documentation on ChannelMonitorUpdateStatus is updated to describe these rules.
The mode tracking and panic checks from 0760f99 are removed and replaced with a panic that validates the new contract directly on the in-flight update state. Legacy tests that switch the persister between modes mid-flight can opt out via Node::disable_monitor_completeness_assertion().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
95/100 · StrongMessage clarity
✓ Specific, 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
defensive validationboot or update path
AI analysis · Low 44/100
This commit fixes a bug where the Lightning Dev Kit (LDK) node software could crash with a false alarm panic. The panic was meant to catch incorrect use of two persistence modes, but it could also fire in legitimate situations because it checked an overridden status value rather than the raw result from the user's persistence code. The fix replaces the broad panic with a more precise rule at the Watch trait level and adds a test-only opt-out for legacy tests that intentionally switch modes mid-flight.
Security candidateValidate all common fields in LSPS1 `is_valid` order checkby Elias Rohrer · 4bec6db5 · Mar 18, 2026 · 1 fileMessage 78 · AdequateLow 47Details
Commit message · Elias Rohrer
Validate all common fields in LSPS1 `is_valid` order check
Add missing cross-validation of `LSPS1OrderParams` against `LSPS1Options` as required by bLIP-51:
- Check `required_channel_confirmations` >= `min_required_channel_confirmations` - Check `funding_confirms_within_blocks` >= `min_funding_confirms_within_blocks` - Check total channel balance (`lsp_balance_sat` + `client_balance_sat`) is within [`min_channel_balance_sat`, `max_channel_balance_sat`], using `checked_add` to guard against overflow
Co-Authored-By: HAL 9000
78/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Names security-relevant behavior explicitly
Why it was queued
memory safetydefensive validation
AI analysis · Low 47/100
This commit fixes validation checks in a Lightning service feature (LSPS1) that lets users place orders for liquidity. Previously, the code did not verify that an order's requested channel size and confirmation settings stayed within the service's advertised limits. The patch adds those missing checks and also protects against a rare integer overflow when adding two balance amounts together. A malicious or malformed order could have slipped through and caused the service to accept terms it never intended to offer.
We plan to have a single channel signer type going forward, so this is unnecessary.
33/100 · OpaqueMessage clarity
✓ Subject identifies a change✓ Provides an explanatory body! Too few words to establish purpose! Opaque security-relevant change
Why it was queued
signing or wallet pathboot or update path
AI analysis · Informational 15/100
This commit is a routine internal code cleanup in the Lightning Dev Kit's Rust implementation. It removes a wrapper type called ChannelSignerType that previously distinguished between different kinds of channel signers, because the project now plans to support only one signer type (ECDSA). The change simplifies function signatures and removes now-unnecessary pattern matching, but does not fix a security bug or change cryptographic behavior.
Taproot support is not planned we see an increase in demand for it by users. The `musig2` crate is now owned by a third-party, and ultimately won't be used by the production version of Taproot that we end up releasing.
51/100 · ThinMessage clarity
✓ Subject identifies a change✓ Provides detailed explanatory context
Why it was queued
signing or wallet pathboot or update path
AI analysis · Informational 15/100
This commit removes an unused experimental Taproot/MuSig2 code path from the rust-lightning project. It deletes the optional `musig2` dependency, removes the `taproot` build flag, and strips out all conditional Taproot-related message fields and serialization logic. There is no indication this fixes a security vulnerability; it is a cleanup change because Taproot support is not currently planned and the external `musig2` crate is now owned by a third party.
Handle FeeRateAdjustmentError variants in splice acceptor path
Replace the generic error handling in splice_init and tx_init_rbf with explicit matching on FeeRateAdjustmentError variants:
- FeeRateTooLow: initiator's feerate is below our minimum. Proceed without contribution and preserve QuiescentAction for an RBF retry at our preferred feerate. - FeeRateTooHigh: initiator's feerate exceeds our maximum and would consume too much of our change output. Reject the splice with WarnAndDisconnect. - FeeBufferInsufficient: our fee buffer can't cover the acceptor's estimated fee at this feerate. Proceed without contribution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundary
AI analysis · Low 44/100
This commit fixes how a Lightning node responds when a peer proposes a splice or RBF transaction fee rate that is too high for the node to afford. Previously, the node would silently drop its own contribution and continue, which could let the peer push through an unexpectedly expensive transaction. Now the node explicitly rejects the splice with a warning and disconnects when the fee rate is too high, while still allowing lower or retryable cases to proceed safely.
Security candidateHandle tx_ack_rbf on the initiator sideby Jeffrey Czyz · b07bfff8 · Mar 12, 2026 · 3 filesMessage 90 · StrongLow 32Details
Commit message · Jeffrey Czyz
Handle tx_ack_rbf on the initiator side
After sending tx_init_rbf, the initiator receives tx_ack_rbf from the acceptor. Implement the handler to validate the response and begin interactive transaction construction for the RBF funding transaction.
Only clear the interactive signing session in `reset_pending_splice_state` when the current funding negotiation is in `AwaitingSignatures`. When an earlier round completed signing and a later RBF round is in `AwaitingAck` or `ConstructingTransaction`, the session belongs to the prior round and must be preserved. Otherwise, disconnecting mid-RBF would destroy the completed prior round's signing session and fire a false debug assertion.
Update test_splice_rbf_acceptor_basic to exercise the full initiator flow: rbf_channel → funding_contributed → STFU exchange → tx_init_rbf → tx_ack_rbf → interactive TX → signing → mining → splice_locked. This replaces the previous test that manually constructed tx_init_rbf.
Co-Authored-By: Claude Opus 4.6 <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
Why it was queued
signing boundarydefensive validation
AI analysis · Low 32/100
This commit adds support in the Lightning Dev Kit for handling a specific protocol message (tx_ack_rbf) when a channel participant initiates a fee-bump (RBF) of a pending splice transaction. Previously, receiving this message caused an error. The change also fixes a related bug where resetting splice state could incorrectly discard a completed signing session from an earlier round, which could trigger a debug assertion. The commit is primarily a feature implementation with a defensive bugfix, not a disclosed security vulnerability.
Security candidateContribute to splice as acceptorby Jeffrey Czyz · d964be91 · Mar 4, 2026 · 3 filesMessage 68 · AdequateLow 33Details
Commit message · Jeffrey Czyz
Contribute to splice as acceptor
When both nodes want to splice simultaneously, the quiescence tie-breaker designates one as the initiator. Previously, the losing node responded with zero contribution, requiring a second full splice session after the first splice locked. This is wasteful, especially for often-offline nodes that may connect and immediately want to splice.
Instead, the losing node contributes to the winner's splice as the acceptor, merging both contributions into a single splice transaction. Since the FundingContribution was originally built with initiator fees (which include common fields and shared input/output weight), the fee is adjusted to the acceptor rate before contributing, with the surplus returned to the change output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundary
AI analysis · Low 33/100
This commit changes how the Lightning Dev Kit handles a rare situation where both sides of a channel try to splice funds at the same time. Previously, the node that lost the tie-breaker would sit out and start a second splice later. Now, the loser contributes its funds to the winner's splice as an 'acceptor,' combining both into one transaction. The change also adjusts fees and change outputs when the winner's chosen fee rate differs from what the loser expected. This is a protocol optimization, not a clear security fix, but it touches fee accounting and transaction construction, which are sensitive areas.
Security candidateAdjust FundingContribution for acceptorby Jeffrey Czyz · 7942c745 · Mar 4, 2026 · 6 filesMessage 58 · ThinLow 44Details
Commit message · Jeffrey Czyz
Adjust FundingContribution for acceptor
When constructing a FundingContribution, it's always assumed the estimated_fee is for when used as the initiator, who pays for the common fields and shared inputs / outputs. However, when the contribution is used as the acceptor, we'd be overpaying fees.
Additionally, the initiator's chosen fee rate may not be compatible with the acceptors contributions. The selected UTXOs may not be enough to pay for a higher feerate (i.e., the change output is not enough to pay or there is no change output).
This change provides a method on FundingContribution for adjusting the fee rate with the above concerns in mind. It also updates it to include a max_feerate specified by the user when initiating a splice. This ensures the acceptor isn't forced to pay an overly high fee rate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit fixes a fee-calculation bug in Lightning splicing. Previously, when both sides tried to splice at the same time, the loser of a tie-break (the 'acceptor') built their contribution as if they were going to pay for the whole shared transaction. That made them overpay fees, and a high fee rate chosen by the other side could drain more from their wallet than intended or even make the transaction invalid. The patch adds logic to re-estimate fees from the acceptor's perspective and lets users set a maximum fee rate they are willing to accept.
Include change output weight in estimate_transaction_fee
Add a `change_output: Option<&TxOut>` parameter to `estimate_transaction_fee` so the initial fee estimate accounts for the change output's weight. Previously, the change output weight was omitted from `estimated_fee` in `FundingContribution`, causing the estimate to be slightly too low when a change output was present.
This also eliminates an unnecessary `Vec<TxOut>` allocation in `compute_feerate_adjustment`, which previously cloned outputs into a temporary Vec just to include the change output for the fee estimate.
A mock `TightBudgetWallet` is added to `splicing_tests` to demonstrate that `validate()` correctly rejects contributions where the input value is sufficient without the change output weight but insufficient with it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundarydefensive validation
AI analysis · Low 37/100
This commit fixes a fee-estimation bug in rust-lightning's channel funding and splicing code. When building a transaction that creates a change output, the code previously forgot to include the change output's size/weight when estimating the required transaction fee. That made the fee estimate slightly too low. The patch adds the missing weight and adds a test showing that a contribution with barely enough money would now be correctly rejected, whereas before it might have been accepted and later failed to broadcast or confirm reliably.
Stop persisting QuiescentAction and remove legacy code
Now that the Splice variant (containing non-serializable FundingContribution) is the only variant produced, and the previous commit consumes the acceptor's quiescent_action in splice_init(), there is no longer a need to persist it. This allows removing LegacySplice, SpliceInstructions, ChangeStrategy, and related code paths including calculate_change_output, calculate_change_output_value, and the legacy send_splice_init method.
With ChangeStrategy removed, the only remaining path in calculate_change_output was FromCoinSelection which always returned Ok(None), making it dead code. The into_interactive_tx_constructor method is simplified accordingly, and the signer_provider parameter is removed from it and from splice_init/splice_ack since it was only needed for the removed change output calculation.
On deserialization, quiescent_action (TLV 65) is still read for backwards compatibility but discarded, and the awaiting_quiescence channel state flag is cleared since it cannot be acted upon without a quiescent_action.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
signing boundary
AI analysis · Low 35/100
This commit removes old, no-longer-used code paths for splicing (a way to resize a Lightning channel). It stops saving a 'quiescent action' to disk because the only remaining variant cannot be serialized, and it drops legacy change-output calculation logic. On loading old data, the stored action is read and then discarded, and the 'awaiting quiescence' flag is cleared so the node does not get stuck waiting for something it can no longer act upon. The change is mostly cleanup and hardening against stale persisted state.
Security candidatePropagate unexpected metadata errors when preserving mtime in fs_storeby benthecarman · 6a43a451 · Feb 25, 2026 · 1 fileMessage 73 · AdequateLow 35Details
Commit message · benthecarman
Propagate unexpected metadata errors when preserving mtime in fs_store
Previously, all fs::metadata errors were silently ignored via .ok(), which could hide permission or I/O errors. Now error are properly handled.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
credential or privilege state
AI analysis · Low 35/100
This change fixes a bug in the file storage component where errors from checking a file's metadata (such as permission denied or disk I/O problems) were silently ignored. Now, most unexpected errors are reported up the chain instead of being swallowed, so the software can react appropriately rather than silently losing information about file modification times.