LDK
← All projectsLightning Dev Kit

rust-lightning

Composable Rust libraries for building Lightning wallets, nodes, and services.

BitcoinCryptographic librariesLightning NetworkNormal
Repository coverage

1497 commits in the local evidence base

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.

225security candidates209second-pass queue1479AI analyses
71commits · 30 days
207commits · 60 days
663commits · 180 days
1488commits · 365 days
Backfill bands
Aug 5 → Feb 6819 seen18 candidatesComplete
Feb 6 → Jun 6468 seen16 candidatesComplete
Jun 6 → Jul 6128 seen8 candidatesComplete
Jul 6 → Aug 561 seen3 candidatesComplete
Commit communication

Does the history explain itself?

Message quality measures whether a commit identifies its scope, purpose, rationale, testing, and supporting references. It does not change the security-severity score.

69/100 average clarity
359Strong · 80–100
790Adequate · 60–79
288Thin · 40–59
60Opaque · 0–39
3security candidates with opaque commit messaging
Read the scoring rubric →
Developer activity

Who is changing the project?

Public Git author strings; identities are not independently verified.

DeveloperCommitsCandidatesAnalyzedHigh riskMessage avg.
Elias Rohrer15315153667
Matt Corallo35847356473
Jeffrey Czyz17741177168
Wilmer Paulino14939149169
Leo Nash11613116162
Valentine Wallace13710135169
Vincenzo Palazzo10210184
Joost Jager16224162069
elnosh301330056
shaavan22622069
Carla Kirk-Cohen78366068
benthecarman18318071
Analysis record

Published AI watches

Last scanned 55 minutes ago

Low 32 AI analysisMessage 91 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Merge PR 'Only fetch TXIDs instead of entire block during gossip verification' (#4846)

This commit changes how the Lightning Dev Kit's block-sync module verifies Lightning network gossip announcements. Instead of downloading entire Bitcoin blocks (which can be large), it now downloads only the list of transaction IDs for a b…

API surface change in UtxoSource traitReduced data exposure: no longer fetches full blocks for gossip verificationNew JSON parsing for txid lists and TxOut values
ebe7a447by Matt Corallo+275−1025 files
No security note in commit
Low 35 AI analysisMessage 81 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Merge PR 'Allow filtered block rescans at the current tip' (#4847)

This commit changes how the Lightning Dev Kit (LDK) node software handles receiving the same block twice through its filtered-block interface. Previously, calling filtered_block_connected with the current tip again would trigger an asserti…

Assertion relaxation in block connection pathPotential denial-of-service vector removed: previously a malicious or buggy filter provider could crash the node by replaying the current tipNew test coverage for same-block filtered rescan
54ddbd0bby Matt Corallo+177−486 files
No security note in commit
Informational 15 AI analysisMessage 83 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Add test framework coverage of `Listen` block connection replays

This commit only adds a new test mode to the project's internal testing framework. It lets developers simulate a specific way blocks are delivered to the Lightning node (a 'replay' through the Listen interface) so that behavior is covered …

bf6ad23eby Matt Corallo+18−32 files
No security note in commit
Informational 15 AI analysisMessage 83 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Update functional test block connection to detect block replays

This commit changes only internal test helper code in the Lightning Dev Kit repository. It makes the functional test framework smarter about 'block replays'—situations where the same block is fed to a test node more than once—so the fake b…

No production code modifiedNo cryptographic, consensus, or networking changesCommit message frames change as test-framework correctness, not security
477facb4by Matt Corallo+41−333 files
No security note in commit
Moderate 66 AI analysisMessage 73 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Correct HTLC confusion on unrevoked counterparty commitment txs

This patch fixes a bug in the Lightning Dev Kit where the software could confuse HTLCs (payment contracts) on live, unrevoked counterparty commitment transactions with ones from old, revoked transactions. Previously, it relied only on whet…

Incorrect revocation state detection for counterparty commitment transactionsHTLC direction not previously checked when matching against pending HTLCsPromotion of debug assertions to full assertions for HTLC claim path consistency
f06a08a6by Matt Corallo+26−192 files
Vendor flagged security relevance
Low 47 AI analysisMessage 85 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Return `Err`s` instead of panicking on oversized messages

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
08f12bc7by Matt Corallo+68−313 files
Vendor flagged security relevance
Moderate 62 AI analysisMessage 85 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Avoid panicking when attempting to send an oversized message

This commit fixes a crash bug in the Lightning Dev Kit's peer message handling. Previously, if a message grew too large to be sent over the encrypted peer connection, the code would panic (abruptly terminate the whole program). The patch m…

Replaces a `.expect()` panic path with a fallible `Result` in peer message encryptionAdds graceful peer disconnection when a critical message cannot be sentIncludes a regression test for oversized-message handling
c5fdc3bfby Matt Corallo+148−901 file
Vendor flagged security relevance
High 74 AI analysisMessage 78 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Avoid oversized relayed failure messages

This patch fixes a crash bug in the Lightning Dev Kit's handling of HTLC failure messages. A downstream peer could send a maximally-sized failure message without attribution data. When the node added its own attribution data while relaying…

Denial-of-service via remote-triggered panic in message encryptionOversized message exceeding Noise/Lightning wire framing limitMissing length validation before adding attribution data during relay
6b1dfb1aby Matt Corallo+64−191 file
Vendor flagged security relevance
Moderate 64 AI analysisMessage 83 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Reject attempts to advance one-hop blinded forward paths

This commit fixes a denial-of-service bug in rust-lightning where a maliciously crafted one-hop blinded reply path could cause the node to panic when it tried to respond. The fix rejects paths with too few hops before advancing them, and a…

Denial-of-service vector via malformed blinded pathPanic in onion construction due to zero-hop pathUntrusted reply path input validation gap
969a40cfby Matt Corallo+49−14 files
Vendor flagged security relevance
High 72 AI analysisMessage 96 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

lightning-types: replace Zl/Zp separators in `PrintableString`

This commit fixes a log-forgery risk in a Rust Lightning library helper called PrintableString. That helper is meant to make untrusted text safe to print by replacing dangerous characters with a placeholder. It already caught most control …

log injection / log forgery via U+2028/U+2029 line separatorsincomplete input sanitisation in PrintableStringpeer-controlled strings (node alias, BOLT 12 description/issuer/payer_note, peer_msg) as attack surface
75defa9cby Vincenzo Palazzo+63−83 files
Vendor flagged security relevance
Moderate 69 AI analysisMessage 73 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Apply the unfunded channel peer limit to all unaccepted channels

This commit fixes a rate-limiting bug in the Lightning Dev Kit (LDK) that let a single peer bypass the cap on how many different peers can have unfunded (not-yet-funded) channels open. Previously, if a peer sent multiple channel requests q…

Denial-of-service resource exhaustion via rapid inbound channel open requestsLogic error in rate-limiting conditionRegression test added for the bypass scenario
56a4ee43by Matt Corallo+87−62 files
Vendor flagged security relevance
Moderate 60 AI analysisMessage 88 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Allow filtered block rescans at the current tip

This commit fixes a bug where replaying the current blockchain block through a normal listener callback could crash two core Lightning components (ChannelManager and OutputSweeper) with a panic. The fix recognizes a same-block replay as a …

panic in chain listener callbacksame-block replay/rescan mishandlingassertion failure on valid chain input
686f9860by Elias Rohrer+118−123 files
Vendor flagged security relevance
Moderate 57 AI analysisMessage 78 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Avoid panic when reorged claims cannot merge

This commit fixes a crash bug in the Lightning Dev Kit's on-chain transaction handler. During a deep blockchain reorganization, a previously settled HTLC claim could be 'resurrected' at a block height where it could no longer be combined w…

Assertion/panic in reorg handling pathDeep blockchain reorg as trigger conditionHTLC claim resurrection after reorg
f1dc8487by Matt Corallo+219−52 files
Vendor flagged security relevance
Informational 15 AI analysisMessage 45 · Thin
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Update crate repository links to forgejo

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…

eb77676dby benthecarman+15−1515 files
No security note in commit
Low 45 AI analysisMessage 73 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Account for message type prefix len in prevtx length enforcement

This commit fixes a small but real accounting bug in how rust-lightning checks whether a previous transaction (prevtx) attached to a funding input will make the resulting Lightning wire message too large. The code previously compared the m…

Off-by-constant length check in protocol message size enforcementPotential acceptance of a prevtx that produces an oversized Lightning wire messageDenial-of-service / protocol-interop risk from peer message rejection
d29e1415by Wilmer Paulino+21−41 file
No security note in commit
Moderate 54 AI analysisMessage 73 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Retransmit splice_locked for 0-conf channels missing tx_signatures

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
5434015bby Wilmer Paulino+266−12 files
No security note in commit
Low 37 AI analysisMessage 83 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

bolt12: add pay_for_bolt12_invoice for externally-sourced invoices

This commit adds a new API, pay_for_bolt12_invoice, that lets users pay a BOLT 12 invoice even if LDK did not originally request it. It is intended for advanced use cases like multi-sender payments and replaces an older, more restrictive A…

New API removes internal invoice-origin verification, shifting trust boundary to callerDocumentation explicitly warns caller to verify invoice via Bolt12Invoice::verify_using_metadata and to ensure unique payment_id to avoid duplicate paymentsInput validation added for zero amount, overpay, and partial-amount-without-MPP
5b80fe9cby Alkamal01+550−156 files
No security note in commit
Low 26 AI analysisMessage 90 · Strong
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Include to_self_delay size in DelayedPaymentOutput weight calculation

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
e6652237by Matt Morehouse+97−83 files
No security note in commit
Informational 18 AI analysisMessage 65 · Adequate
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

Correct docs on `ChannelSigner::get_per_commitment_point`

This commit only updates documentation comments for a Rust function called get_per_commitment_point. It removes an outdated warning that the method was non-asynchronous and that returning an error could cause a crash, and replaces it with …

Documentation-only changeRemoves outdated panic warningAdds retry/unblock guidance for signer errors
5057809bby Matt Corallo+6−31 file
No security note in commit
Informational 16 AI analysisMessage 35 · Opaque
LDK Lightning Dev Kitrust-lightning BitcoinCryptographic librariesLightning Network

ln/refactor: remove BlindedTrampolineEntrypoint

This commit is a small internal code cleanup in the Lightning Dev Kit's Trampoline routing code. It removes a separate 'BlindedTrampolineEntrypoint' payload variant and folds an optional blinding point into the existing 'Forward' variant. …

Refactor-only change with no added bounds checks or validationNo mention of vulnerability, CVE, security fix, or bug in commit messageTLV field changed from required to optional, but only for a newly unified variant used in internal construction
3e0c2697by Carla Kirk-Cohen+8−263 files
No security note in commit
Repository ledger

Explore captured commits

Expand any commit for its author, full message, clarity score, changed files, triage signals, analysis, and source link.

Lower-priorityAdd clarifying comment to signer_maybe_unblockedby Jeffrey Czyz · de65412a · Aug 26, 2025 · 1 fileMessage 45 · ThinInformational 15Details
Commit message · Jeffrey Czyz

Add clarifying comment to signer_maybe_unblocked

45/100 · ThinMessage clarity
✓ Descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
AI analysis · Informational 15/100

This commit only adds a clarifying code comment explaining why a specific transaction number is used when building a commitment transaction. No code behavior was changed, so there is no security impact.

Lower-priorityInclude fees in SpliceContribution docsby Jeffrey Czyz · 8213f65d · Aug 25, 2025 · 1 fileMessage 68 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Include fees in SpliceContribution docs

How fees are paid for in a SpliceContribution depends on whether it is a
SpliceIn or SpliceOut. Include this in its docs for clarification.

68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit only updates documentation comments for the SpliceContribution type. It clarifies that users must account for transaction fees when providing inputs for a splice-in or outputs for a splice-out. No code behavior changed.

Lower-priorityFix debug_assert on our_funding_contributionby Jeffrey Czyz · 9fa6e3c6 · Aug 25, 2025 · 1 fileMessage 58 · ThinInformational 16Details
Commit message · Jeffrey Czyz

Fix debug_assert on our_funding_contribution

When processing a splice_ack, the debug_assert on the range of
our_funding_contribution should account for values that are for both
positive (splice-in) and negative (splice-out).

58/100 · ThinMessage clarity
✓ Descriptive subject✓ Provides detailed explanatory context
AI analysis · Informational 16/100

This commit fixes a sanity check (debug_assert) used during a new experimental feature called splicing in the Lightning Dev Kit. The check previously only accepted positive funding contributions, but splicing can also involve negative contributions (splice-out). The fix makes the check use the absolute value. This is a debug-only assertion, so it only affects test/debug builds and cannot be exploited in production release builds.

Lower-priorityAdd splice-out supportby Jeffrey Czyz · 3245ebff · Aug 25, 2025 · 4 filesMessage 51 · ThinLow 32Details
Commit message · Jeffrey Czyz

Add splice-out support

Update SpliceContribution with a variant used to support splice-out
(i.e., removing funds from a channel). The TxOut values must not exceed
the users channel balance after accounting for fees and the reserve
requirement.

51/100 · ThinMessage clarity
✓ Subject identifies a change✓ Provides detailed explanatory context
AI analysis · Low 32/100

This commit adds 'splice-out' support to the Lightning Dev Kit, allowing users to remove funds from an existing channel while keeping the channel open. The change introduces new code paths that handle negative contributions (removing funds) and adds checks to ensure the user cannot remove more than their channel balance after accounting for fees and reserve requirements. It is a feature addition, not a documented security fix, but it touches sensitive financial-validation logic.

Lower-prioritySupport accepting splice-outby Jeffrey Czyz · ce203f27 · Aug 25, 2025 · 1 fileMessage 58 · ThinLow 42Details
Commit message · Jeffrey Czyz

Support accepting splice-out

When a counterparty sends splice_init with a negative contribution, they
are requesting to remove funds from a channel. Remove conditions
guarding against this and check that they have enough channel balance to
cover the removed funds.

58/100 · ThinMessage clarity
✓ Descriptive subject✓ Provides detailed explanatory context
AI analysis · Low 42/100

This commit adds support for 'splice-out', a way for a Lightning channel partner to remove funds from an existing channel rather than only adding funds. Previously, the code rejected negative contribution values outright. The change removes that blanket rejection and adds checks to ensure the counterparty actually has enough balance in the channel to cover the requested withdrawal. It also centralizes validation of the counterparty's splice contribution in a new helper function used in both incoming and outgoing splice paths.

Lower-priorityUse a SpliceContribution enum for passing splice-in paramsby Jeffrey Czyz · ae58a4f6 · Aug 25, 2025 · 4 filesMessage 73 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Use a SpliceContribution enum for passing splice-in params

ChannelManager::splice_channel takes individual parameters to support
splice-in. Change these to an enum such that it can be used for
splice-out as well.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a straightforward code refactor. It bundles several parameters related to adding funds to a Lightning channel (a 'splice-in') into a single new enum called SpliceContribution. The goal is to make the API cleaner and prepare it for a future 'splice-out' feature. There is no security fix or vulnerability here.

Lower-priorityReplace funding input tuple with structby Jeffrey Czyz · bdb8d5d8 · Aug 25, 2025 · 7 filesMessage 68 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Replace funding input tuple with struct

The funding inputs used for splicing and v2 channel establishment are
passed as a tuple of txin, prevtx, and witness weight. Add a struct so
that the items included can be better documented.

68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a straightforward internal code cleanup in the Lightning Dev Kit's rust-lightning project. It replaces a plain tuple (a simple grouping of three related pieces of data) with a named struct called FundingTxInput for funding inputs used in splicing and v2 channel establishment. The change improves code readability and documentation but does not fix a security bug or change user-facing behavior in a security-relevant way.

Lower-priorityRename ChannelContext::counterparty_prev_commitment_pointby Jeffrey Czyz · 6bde10ca · Aug 22, 2025 · 1 fileMessage 63 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Rename ChannelContext::counterparty_prev_commitment_point

To align with the "current" and "next" nomenclature used by
HolderCommitmentPoint, update the naming of the counterparty commitment
point field to use "current" instead of "previous".

63/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a pure internal rename of a variable from 'previous' to 'current' to make the code easier to understand. No behavior changed, and there is no security issue.

Lower-priorityRename ChannelContext::counterparty_cur_commitment_pointby Jeffrey Czyz · a6cef30b · Aug 22, 2025 · 1 fileMessage 63 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Rename ChannelContext::counterparty_cur_commitment_point

To align with the "current" and "next" nomenclature used by
HolderCommitmentPoint, update the naming of the counterparty commitment
point field to use "next" instead of "current".

63/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a simple rename of an internal variable from 'current' to 'next' to make the code's naming more consistent. It does not change any program logic, security behavior, or data format. There is no security issue here.

Lower-priorityRename ChannelContext::cur_counterparty_commitment_transaction_numberby Jeffrey Czyz · 9d7ec5f2 · Aug 22, 2025 · 1 fileMessage 63 · AdequateInformational 15Details
Commit message · Jeffrey Czyz

Rename ChannelContext::cur_counterparty_commitment_transaction_number

To align with the "current" and "next" nomenclature used by
HolderCommitmentPoint, update the naming of the counterparty commitment
transaction number field to use "next" instead of "current".

63/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a simple rename of an internal variable from 'cur_counterparty_commitment_transaction_number' to 'counterparty_next_commitment_transaction_number' to make the naming more consistent with other parts of the code. There are no functional changes, no bug fixes, and no security implications.

Lower-priorityReturn ChannelError instead of calling expectby Jeffrey Czyz · 1f8a7d78 · Aug 21, 2025 · 1 fileMessage 45 · ThinLow 42Details
Commit message · Jeffrey Czyz

Return ChannelError instead of calling expect

45/100 · ThinMessage clarity
✓ Descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
AI analysis · Low 42/100

This change replaces a hard program crash (an 'expect' call that would terminate the node) with a graceful error return when a specific piece of channel state is missing during a splicing operation. Instead of the entire Lightning node panicking and shutting down, the node now reports a controlled channel-closing error. This is a defensive improvement that reduces denial-of-service risk from malformed or unexpected peer messages, but the commit itself does not claim a security vulnerability was fixed.

Lower-priorityDelete dead `next_{local, remote}_commitment_tx_fee_info_cached`by Leo Nash · f75812ff · Aug 21, 2025 · 1 fileMessage 75 · AdequateInformational 14Details
Commit message · Leo Nash

Delete dead `next_{local, remote}_commitment_tx_fee_info_cached`

The cached fee is never checked in the current test suite.

75/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides an explanatory body✓ Mentions testing or verification
AI analysis · Informational 14/100

This commit removes unused test-only code that cached predicted commitment transaction fees. The removed fields were only compiled under test/fuzzing configurations and were never checked by the current test suite. The commit does not change production behavior or fix any security issue.

Lower-priorityAdd validation of the fees predicted by `next_commitment_stats`by Leo Nash · 8a1c9d94 · Aug 21, 2025 · 1 fileMessage 73 · AdequateLow 27Details
Commit message · Leo Nash

Add validation of the fees predicted by `next_commitment_stats`

Anytime we build a (feerate, nondust-htlc-count, fee) pair, cache it,
and check that the fee matches if the feerate and nondust-htlc-count
match when building a commitment transaction.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 27/100

This commit adds internal bookkeeping and consistency checks to make sure the fee predicted when planning a Lightning channel commitment transaction matches the fee actually used when the transaction is later built. It only runs during tests and fuzzing, so it does not directly change production behavior. It is a defensive hardening/debugging patch rather than a fix for an active exploit.

Lower-priorityImprove prediction of commitment stats in `can_accept_incoming_htlc`by Leo Nash · 3218db15 · Aug 21, 2025 · 2 filesMessage 73 · AdequateModerate 63Details
Commit message · Leo Nash

Improve prediction of commitment stats in `can_accept_incoming_htlc`

`ChannelContext::get_pending_htlc_stats` predicts that the set of HTLCs
on the next commitment will be all the HTLCs in
`ChannelContext.pending_inbound_htlcs`, and
`ChannelContext.pending_outbound_htlcs`, as well as all the outbound
HTLC adds in the holding cell.

This is an overestimate:

* Outbound HTLC removals which have been ACK'ed by the counterparty will
certainly not be present in any *next* commitment, even though they
remain in `pending_outbound_htlcs`.

* Outbound HTLCs in the `RemoteRemoved` state, will not be present in
the next *local* commitment.

* Outbound HTLCs in the `LocalAnnounced` state have no guarantee that
they were yet received by the counterparty.

* Outbound `update_add_htlc`'s in the holding cell are certainly not
known by the counterparty, and we will reevaluate their addition to
the channel when freeing the holding cell.

* Inbound HTLCs in the `LocalRemoved` state will not be present in the
next *remote* commitment.

This commit stops using `get_pending_htlc_stats` in favor of the newly
added `ChannelContext::get_next_{local, remote}_commitment_stats`
methods, and fixes the issues described above.

`ChannelContext::next_remote_commit_tx_fee_msat` counts inbound HTLCs in
the `LocalRemoved` state, as well as outbound HTLCs in the
`LocalAnnounced` state. We now do not count them for the same reasons
described above.

Inbound `LocalRemoved` HTLCs that were **not** successful are now
credited to `remote_balance_before_fee_msat` as they will certainly not
be on the next remote commitment. We previously debited these from the
remote balance to arrive at `remote_balance_before_fee_msat`.

We now always check holder dust exposure, whereas we previously would
only do it if the incoming HTLC was dust on our own commitment
transaction.

Furthermore, dust exposure calculations now take a buffer from the
currently committed feerate, and ignore any fee updates in
`ChannelContext.pending_update_fee`.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 63/100

This commit fixes how a Lightning node predicts the contents of its next commitment transactions when deciding whether to accept an incoming payment (HTLC). Previously, the node overestimated which HTLCs would appear on the next commitment, which could cause it to wrongly reject valid incoming payments (a denial-of-service/availability issue) or apply incorrect fee and dust checks. The patch replaces the overestimate with more precise per-commitment statistics and tightens dust-exposure checks for the node's own commitment transaction.

Lower-priorityAdd `ChannelContext::get_next_{local, remote}_commitment_stats`by Leo Nash · 06ed9cb5 · Aug 21, 2025 · 1 fileMessage 73 · AdequateInformational 11Details
Commit message · Leo Nash

Add `ChannelContext::get_next_{local, remote}_commitment_stats`

In upcoming commits, these methods will serve as proxies to
`SpecTxBuilder::get_next_commitment_stats` in all validation of channel
updates in `ChannelContext`.

Eventually, these methods will completely replace
`get_pending_htlc_stats`, and
`get_next_{local, remote}_commit_tx_fee_msat`.

When predicting the HTLCs on next commitment, we take the conservative
approach and only assume that a HTLC will not be in the next commitment
when it is guaranteed that it won't be.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 11/100

This commit adds four new private helper methods to the Lightning channel code. The methods are marked `#[allow(dead_code)]`, meaning they are not yet called anywhere. They are intended to replace older balance/fee estimation helpers in future commits. There is no functional change to how channels are validated today, and no security fix or vulnerability is introduced in this patch.

Lower-priorityImprove prediction of commitment stats in `can_send_update_fee`by Leo Nash · 124bd421 · Aug 21, 2025 · 1 fileMessage 73 · AdequateModerate 63Details
Commit message · Leo Nash

Improve prediction of commitment stats in `can_send_update_fee`

`ChannelContext::get_pending_htlc_stats` predicts that the set of HTLCs
on the next commitment will be all the HTLCs in
`ChannelContext.pending_inbound_htlcs`, and
`ChannelContext.pending_outbound_htlcs`, as well as all the outbound
HTLC adds in the holding cell.

This is an overestimate:

* Outbound HTLC removals which have been ACK'ed by the counterparty will
certainly not be present in any *next* commitment, even though they
remain in `pending_outbound_htlcs` (I refer to states
`AwaitingRemoteRevokeToRemove` and `AwaitingRemovedRemoteRevoke`).

* Outbound HTLCs in the `RemoteRemoved` state, will not be present in
the next *local* commitment.

* Inbound HTLCs in the `LocalRemoved` state will not be present in the
next *remote* commitment.

`ChannelContext::build_commitment_stats(funding, true, true, ..)` makes
these errors when predicting the HTLC count on the remote commitment:

* Inbound HTLCs in the state `RemoteAnnounced` are not included, but
they will be in the next remote commitment transaction if the local
ACK's the addition before producing the next remote commitment.

* Inbound HTLCs in the state `AwaitingRemoteRevokeToAnnounce` are not
included, even though the local has ACK'ed the addition.

* Outbound HTLCs in the state `AwaitingRemoteRevokeToRemove` are
counted, even though the local party has ACK'ed the removal.

This commit replaces these functions in favor of the newly added
`ChannelContext::get_next_{local, remote}_commitment_stats` methods,
and fixes the issues described above.

We now always calculate dust exposure using a buffer from
`msg.feerate_per_kw`, and not from
`max(feerate_per_kw, self.feerate_per_kw, self.pending_update_fee)`.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Moderate 63/100

This commit fixes how a Lightning node predicts the contents of its next commitment transactions when deciding whether it can safely propose a fee update. Previously the code over- or under-counted pending HTLCs depending on their state, which could let the node accept a feerate that leaves it unable to pay the resulting commitment transaction fee or reserve, or that exceeds dust-exposure safety limits. The fix replaces the old prediction helpers with new state-aware methods that model the next local and remote commitments more accurately.

Lower-priorityImprove prediction of commitment stats in `validate_update_add_htlc`by Leo Nash · 48b412a4 · Aug 21, 2025 · 1 fileMessage 73 · AdequateModerate 63Details
Commit message · Leo Nash

Improve prediction of commitment stats in `validate_update_add_htlc`

`ChannelContext::get_pending_htlc_stats` predicts that the set of HTLCs
on the next commitment will be all the HTLCs in
`ChannelContext.pending_inbound_htlcs`, and
`ChannelContext.pending_outbound_htlcs`, as well as all the outbound
HTLC adds in the holding cell.

This is an overestimate:

* Outbound HTLC removals which have been ACK'ed by the counterparty will
certainly not be present in any *next* commitment, even though they
remain in `pending_outbound_htlcs`.

* Outbound HTLCs in the `RemoteRemoved` state, will not be present in
the next *local* commitment.

* Outbound HTLCs in the `LocalAnnounced` state have no guarantee that
they were received by the counterparty before she sent the
`update_fee`.

* Outbound `update_add_htlc`'s in the holding cell are certainly not
known by the counterparty, and we will reevaluate their addition to
the channel when freeing the holding cell.

* Inbound HTLCs in the `LocalRemoved` state will not be present in the
next *remote* commitment.

`ChannelContext::next_local_commit_tx_fee_msat` over-counts outbound
HTLCs in the `LocalAnnounced` and `RemoteRemoved` states, as well as
outbound `update_add_htlc`'s in the holding cell.

`ChannelContext::next_remote_commit_tx_fee_msat` over-counts inbound
HTLCs in the `LocalRemoved` state, as well as outbound HTLCs in the
`LocalAnnounced` state.

This commit stops using these functions in favor of the newly added
`ChannelContext::get_next_{local, remote}_commitment_stats` methods,
and fixes the issues described above.

If we are the funder, we also check that adding this inbound HTLC
doesn't increase the commitment transaction fee to the point of
exhausting our balance on the local commitment. Previously, we would
only subtract the anchors from `funding.value_to_self_msat`; we now
also subtract the outbound HTLCs on the next local commitment from
`funding.value_to_self_msat` before checking if we can afford the
additional transaction fees.

Inbound `LocalRemoved` HTLCs that were **not** successful are now
credited to `remote_balance_before_fee_msat` as they will certainly not
be on the next remote commitment. We previously debited these from the
remote balance to arrive at `remote_balance_before_fee_msat`.

When calculating dust exposure, we now take a buffer from the currently
committed feerate, and ignore any fee updates in
`ChannelContext.pending_update_fee`.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
defensive validation
AI analysis · Moderate 63/100

This commit fixes how a Lightning node predicts which pending payments (HTLCs) will actually appear on the next commitment transaction when validating a new incoming HTLC. The old code over-counted HTLCs, which could cause the node to reject valid HTLCs or, more importantly, accept HTLCs while miscalculating whether the remote party can afford the on-chain fees and channel reserve. The patch also improves the funder's check so it subtracts outbound HTLCs from its own balance before checking fee affordability, and fixes a balance-credit bug for inbound HTLCs being removed. In short, it tightens the economic safety checks that prevent a channel from being created with terms one side cannot actually honor on-chain.

AI review queuedAdd `TxBuilder::get_next_commitment_stats`by Leo Nash · 0a75f927 · Aug 21, 2025 · 2 filesMessage 58 · ThinInformational 11Details
Commit message · Leo Nash

Add `TxBuilder::get_next_commitment_stats`

Given a snapshot of the lightning state machine,
`TxBuilder::get_next_commitment_stats` calculates the transaction fees,
the dust exposure, and the holder and counterparty balances
(the balances themselves do *not* account for the transaction fee).

58/100 · ThinMessage clarity
✓ Descriptive subject✓ Provides detailed explanatory context
Why it was queued
signing or wallet pathsecond-pass: security-sensitive path
AI analysis · Informational 11/100

This commit adds a new internal helper method that estimates the fees, dust exposure, and balances for a future Lightning channel commitment transaction. It does not change any existing behavior or fix a known bug; it appears to be preparatory/refactoring work to support future channel-fee logic. There is no indication in the commit that it addresses a security vulnerability.

AI review queuedAdjust dust exposure due to excess fees for clarityby Leo Nash · 3a3e7eb8 · Aug 21, 2025 · 1 fileMessage 62 · AdequateInformational 12Details
Commit message · Leo Nash

Adjust dust exposure due to excess fees for clarity

62/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Explains rationale or failure mode! No meaningful explanatory body
Why it was queued
signing or wallet pathsecond-pass: security-sensitive path
AI analysis · Informational 12/100

This commit is a code clarity and variable-naming refactor in a function that calculates how much money a Lightning channel could lose due to tiny ('dust') transactions plus extra fees. It renames variables, removes an unnecessary mutable parameter, and reorders calculations so the math is easier to follow. The actual arithmetic result appears unchanged, so this is not a security fix.

Lower-priorityImprove prediction of commitment stats in `validate_update_fee`by Leo Nash · d36fdabe · Aug 21, 2025 · 1 fileMessage 73 · AdequateModerate 61Details
Commit message · Leo Nash

Improve prediction of commitment stats in `validate_update_fee`

`ChannelContext::get_pending_htlc_stats` predicts that the set of HTLCs
on the next commitment will be all the HTLCs in
`ChannelContext.pending_inbound_htlcs`, and
`ChannelContext.pending_outbound_htlcs`, as well as all the outbound
HTLC adds in the holding cell.

This is an overestimate:

* Outbound HTLC removals which have been ACK'ed by the counterparty will
certainly not be present in any *next* commitment, even though they
remain in `pending_outbound_htlcs`.

* Outbound HTLCs in the `RemoteRemoved` state, will not be present in
the next *local* commitment.

* Outbound HTLCs in the `LocalAnnounced` state have no guarantee that
they were received by the counterparty before she sent the
`update_fee`.

* Outbound `update_add_htlc`'s in the holding cell are certainly not
known by the counterparty, and we will reevaluate their addition to
the channel when freeing the holding cell.

* Inbound HTLCs in the `LocalRemoved` state will not be present in the
next *remote* commitment.

This commit stops using `get_pending_htlc_stats` in favor of the newly
added `ChannelContext::get_next_{local, remote}_commitment_stats`
methods, and fixes the issues described above.

We now always calculate dust exposure using a buffer from
`msg.feerate_per_kw`, and not from
`max(self.feerate_per_kw, msg.feerate_per_kw)`.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
defensive validation
AI analysis · Moderate 61/100

This patch tightens how a Lightning node estimates which pending payments (HTLCs) will actually appear on the next commitment transaction when checking a peer's proposed fee rate. Previously the node counted HTLCs that might already be removed or not yet known to the peer, which could cause it to reject valid fee updates or, conversely, accept fee updates that expose it to more 'dust' HTLC risk than intended. The change makes the dust-exposure check more accurate by predicting the next local and next remote commitment separately and using only the new fee rate for the dust buffer.

Lower-priorityRemove now-unused ServeStaticInvoice::invoice_idby Valentine Wallace · e159ae42 · Aug 21, 2025 · 5 filesMessage 68 · AdequateInformational 15Details
Commit message · Valentine Wallace

Remove now-unused ServeStaticInvoice::invoice_id

In the initially-merged version of the static invoice server protocol, the
static invoice server would sometimes have to find a specific static invoice
based on (recipient_id, invoice_slot) and sometimetimes based on (recipient_id,
invoice_id). This made the API harder to use in terms of how the server would
index into the KVStore.

Over the course of the previous commits we transitioned to the server always
finding a specific invoice based on (recipient_id, invoice_slot). We still have
a few dangling references to invoice_id in some messages and events though, so
remove those here.

68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a routine cleanup of an internal messaging protocol. It removes a now-unused field called invoice_id and standardizes on a different identifier (invoice_slot) for looking up stored invoices. There is no security fix here; it is purely a simplification of the code and data structures.

Lower-priorityReplace StaticInvoiceReq::invoice_id with ::inv_slotby Valentine Wallace · f53325bf · Aug 21, 2025 · 5 filesMessage 73 · AdequateInformational 15Details
Commit message · Valentine Wallace

Replace StaticInvoiceReq::invoice_id with ::inv_slot

In the initially-merged version of the static invoice server protocol, the
static invoice server would sometimes have to find a specific static invoice
based on (recipient_id, invoice_slot) and sometime based on (recipient_id,
invoice_id). This made the API harder to use in terms of how the server would
index into the KVStore.

We'd like to transition to the server always finding a specific invoice based on
(recipient_id, invoice_slot) and get rid of the invoice_id concept.

Previously, when an invoice request would come in for the server on behalf of
the often-offline recipient, they would need to find the static invoice based
on the recipient_id and invoice_id. However, previous commits have now led to
the server being able to use the invoice_slot in the initial offer paths that
they create, which we do here, obviating the need for them to create their own
randomly-generated invoice_id. The final dangling references to the invoice_id
will be removed in the next commit.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100

This commit is a straightforward internal API cleanup in the experimental static-invoice-server protocol. It replaces a randomly-generated 128-bit invoice_id with a simpler 16-bit invoice_slot when looking up stored invoices. There is no security fix here—just making the database lookup key consistent and easier to use.

Lower-priorityRemove now-unused ServeStaticInv::inv_slot from OMby Valentine Wallace · 06f20197 · Aug 21, 2025 · 3 filesMessage 73 · AdequateInformational 18Details
Commit message · Valentine Wallace

Remove now-unused ServeStaticInv::inv_slot from OM

In the initially-merged version of the static invoice server protocol, the
static invoice server would sometimes have to find a specific static invoice
based on (recipient_id, invoice_slot) and sometime based on (recipient_id,
invoice_id). This made the API harder to use in terms of how the server would
index into the KVStore.

We'd like to transition to the server always finding a specific invoice based on
(recipient_id, invoice_slot) and get rid of the invoice_id concept.

In the previous commit the server began including the invoice_slot in the
ServeStaticInvoice blinded path context that gets provided back to themselves.
Therefore there is no need for the recipient to redundantly include it in the
ServeStaticInvoice onion message itself.

73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 18/100

This commit removes an unused data field called invoice_slot from a message type used in a new Lightning protocol feature for storing static invoices on a server. The change is described by the developers as a cleanup to simplify how the server looks up stored invoices. There is no indication in the commit that this fixes a security bug; it appears to be a normal API and protocol simplification.

Lower-priorityTrack invoice_slot in ServeStaticInvoice contextby Valentine Wallace · 748c04a0 · Aug 21, 2025 · 3 filesMessage 80 · StrongInformational 18Details
Commit message · Valentine Wallace

Track invoice_slot in ServeStaticInvoice context

In the initially-merged version of the static invoice server protocol, the
static invoice server would sometimes have to find a specific static invoice
based on (recipient_id, invoice_slot) and sometime based on (recipient_id,
invoice_id). This made the API harder to use in terms of how the server would
index into the KVStore.

We'd like to transition to the server always finding a specific invoice based on
(recipient_id, invoice_slot) and get rid of the invoice_id concept.

As part of this series of commits, include the invoice_slot in the
ServeStaticInvoice blinded path context that the server creates when sending an
offer_paths message. This is possible due to a previous commit including the
invoice_slot in the initial offer_paths_request from the recipient, and lays
the groundwork for removing the invoice_id field from this blinded path
context.

80/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Informational 18/100

This commit is a small internal cleanup in the code that handles static Lightning invoices. It makes the software remember an 'invoice_slot' number earlier in the process so that later, when serving a stored invoice, the server can look it up by slot number instead of relying only on an 'invoice_id'. The change adds a new field to a protocol data structure and threads it through the request/response flow. There is no indication this fixes a security bug; it appears to be a design/API simplification.

Lower-priorityCache pending offer in specific invoice slotby Valentine Wallace · ed0bf367 · Aug 21, 2025 · 3 filesMessage 68 · AdequateLow 26Details
Commit message · Valentine Wallace

Cache pending offer in specific invoice slot

When we as an async recipient receive offer paths from the static invoice server,
we create an offer and cache it, retrying persisting a corresponding invoice with
the server until it succeeds.

In the initially-merged version of this protocol, we would put this cached
offer in any slot in the cache that needed an offer at the time the offer paths
were received. However, in the last commit we started requesting offer paths
for a specific slot in the cache, as part of eliminating the use of the
invoice_id field in the overall protocol.

As a result, here we put the cached offer in the specific cache slot that the
original OfferPathsRequest indicated, rather than any slot that could use a new
offer.

68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Low 26/100

This commit tightens up how a Lightning node caches payment offers when receiving them from a static invoice server. Previously, the node would place a newly received offer into any open slot in its cache. After this change, it stores the offer only in the specific slot it originally requested. The change is part of a protocol cleanup to remove reliance on an invoice_id field. It is primarily a correctness and protocol-consistency fix rather than a clear security patch, though the old behavior could theoretically have allowed a server to confuse or overwrite unrelated cached offers.