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 makes on-chain 'MonitorEvent' notifications durable and replay-safe. Previously, if a node crashed after a ChannelMonitor persisted a block update but before the ChannelManager processed the resulting event, the event could be …
Durability/atomicity fix for async persistence: prevents lost MonitorEvents across crashesNew ack-based event lifecycle with random event IDsArchival gating on unacknowledged events to avoid losing preimage/timeout information
This commit refactors how LDK nodes claim incoming Lightning payments. It replaces a separate 'claim with known custom TLVs' method with an options struct passed to the normal claim call, and fixes two edge cases in payment attribution dat…
API change: claim_funds now takes ClaimFundsOptions, consolidating TLV-known behavior into one pathFailure-packet length bound added to prevent oversized onion error messagesIncoming failure packet truncated at 32 KiB before processing
This change fixes a wallet bookkeeping problem in rust-lightning's built-in coin-selection wrappers. Previously, when a splice attempt failed or coin selection errored after picking UTXOs, those UTXOs stayed marked as 'reserved' in memory …
Resource exhaustion / denial-of-service via permanent in-memory UTXO reservationIncorrect state tracking in coin-selection wrapperNew API method required for correct lifecycle management (release_utxos)
This commit fixes a bug in the wallet's coin-selection code. When the wallet picked UTXOs to spend, it locked them immediately so they couldn't be reused. But if a later step—fetching the change address or the previous transaction—failed, …
Resource lock leak on error pathUTXO lock state inconsistency between selection and confirmationDenial-of-service/funds-unavailability risk from persistent UTXO locks
This commit rewrites how a Lightning wallet talks to Esplora block-explorer servers so that many status checks happen in parallel instead of one at a time. It is a performance/refactoring change. There is no direct evidence in the commit t…
Concurrency/timing change in transaction confirmation logicNew inconsistency check preserved when a previously-confirmed tx is reported unconfirmedAdded defensive error path for missing pre-fetched block status
This change stops the Electrum-based transaction sync client from downloading the very transaction that created an output it is watching. Previously, the client could request that transaction from Electrum, even though a transaction can ne…
Avoids unnecessary Electrum transaction.get requests for watched outputsReduces information disclosure to Electrum server about watched outpointsAdds regression test verifying request suppression
This change improves how the Lightning Dev Kit's Electrum and Esplora transaction-sync clients track watched Bitcoin transactions. Previously, the code ignored the script pubkey (the 'address' associated with a transaction) supplied when r…
Previously ignored `script_pubkey` argument in `register_tx` for transaction watchersElectrum script-history queries previously used an arbitrary transaction output, which could be OP_RETURN and therefore unindexed by some Electrum serversNew logic prefers caller-supplied script pubkey and falls back to non-OP_RETURN outputs
This commit changes how LDK stores pending event notifications. It adds serialization support for several event types that previously were not fully saved to disk, and introduces a helper method so the code can decide which events are wort…
Data-loss prevention: previously non-round-trippable event variants are now fully serialized, avoiding accidental event loss when users serialize Event queues themselvesState-consistency hardening: ChannelManager now explicitly skips events that describe non-surviving restart state, preventing replay of stale eventsDefensive assertion: debug builds assert that every persisted event round-trips to Some(event), catching serialization mismatches
This commit only adds documentation comments to two source files. It explains that certain funding-signing events can become stale if the underlying negotiation fails, and that callers may see specific harmless errors as a result. No code …
This commit fixes a design flaw in LDK's built-in wallet helper where coins selected for a splice-in (or other unclaimed funding) were permanently reserved in memory if the transaction was abandoned. Over repeated failed splices, all spend…
Denial-of-service via UTXO exhaustion from repeated failed splice negotiationsRisk of inability to broadcast fee-bumping/claim transactions due to lack of available UTXOsNew API surface (release_utxos) introduced to mitigate resource leak
This commit removes a fixed-version pin for the honggfuzz fuzzing tool in a continuous-integration script. The project now uses the current release of honggfuzz instead of an older pinned version. There is no change to the actual Lightning…
This commit changes the Rust toolchain used in the continuous integration (CI) fuzzing job from a fixed older version (1.75) to the latest stable release. It is purely a build/test infrastructure change to fix a dependency compatibility is…
This commit makes a previously internal helper function public so that outside developers can build dummy-hop tails for blinded payment paths without recreating the logic themselves. It is an API usability change, not a fix for a known sec…
No security-relevant behavior change in the diffAPI visibility broadened from crate-public to publicCLTV expiry overflow check already present and unchanged
This change adds a safety check in a Bitcoin Lightning Network library (LDK). Previously, if the software tried to verify a peer's commitment signature before it had learned the peer's channel parameters, it could crash with a panic. Now i…
Defensive check added on peer-driven code path to prevent panicMissing counterparty_parameters could previously cause panic during commitment transaction constructionChannel closure returned instead of panic
This commit only changes the wording of an error message sent to peers when a commitment transaction fails validation. It replaces the vague phrase 'Failed to validate our commitment' with the clearer 'Received commitment failed validation…
This commit moves the checks that validate a counterparty's signatures on the holder's commitment and HTLC transactions out of the general channel code and into the signer module (InMemorySigner). Previously, these signature checks were do…
Moved signature validation from channel state machine into signer moduleAdded new tests that corrupt signatures and verify rejectionChanged error message from 'Invalid commitment tx signature from peer' / 'Invalid funding_created signature from peer' to 'Failed to validate our commitment'
This change fixes a Lightning channel splicing bug: when two peers temporarily disconnect during a splice, any half-finished signature the other side already sent is now discarded. Before the fix, that stale signature could be reused after…
State-invalidation bug in multi-step protocol (splice negotiation)Stale cryptographic signature not cleared on disconnectPotential reuse of old commitment state after reconnect
This fix prevents a Lightning channel from being accidentally force-closed. During a splice (a way to resize a payment channel), one side's initial signature could be kept in memory after the peers disconnected. If the peers later reconnec…
State inconsistency: in-memory buffered message not cleared on disconnectDuplicate message processing after reconnectionForce-close consequence for active Lightning channel
This commit is a simple rename of a public function from `matches_invoice_signing_pubkey` to `key_can_sign_invoice`, plus matching updates to its documentation, callers, tests, and changelog. No behavior changed. It is not a security fix.
This commit is a simple rename of a function and its documentation from matches_invoice_signing_pubkey to key_can_sign_invoice. No logic, behavior, or security properties changed. It is a follow-up code-review naming cleanup.
Gate all SystemTime::now() and Instant::now() calls in production code with #[cfg(all(feature = "std", not(fuzzing)))] so that fuzz targets produce consistent results regardless of wall-clock time. For each location, the existing no-std fallback (highest_seen_timestamp, None, or a constant) is reused under fuzzing.
Also force deterministic hashing when the fuzzing cfg is active, rather than requiring the LDK_TEST_DETERMINISTIC_HASHES env var.
AI tools were used in preparing this commit.
80/100 · StrongMessage clarity
✓ Descriptive subject✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Informational 19/100
This commit changes how the Lightning Dev Kit code behaves when running under fuzz testing. Normally, the code uses the real wall-clock time and random hashing. Under fuzzing, it now uses fixed fallback values and deterministic hashing so that fuzz tests produce the same results every run. This is a testing-harness improvement, not a fix for an exploitable security bug in production. It does not change behavior for normal users.
Lower-priorityDocument that `Future` callbacks are not reentrant-safeby Matt Corallo · b06ba3fe · Apr 1, 2026 · 1 fileMessage 65 · AdequateLow 26Details
Commit message · Matt Corallo
Document that `Future` callbacks are not reentrant-safe
Claude was complaining about this, and it seems worth documenting, but not worth (and kinda hard to) fix.
65/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides an explanatory body
AI analysis · Low 26/100
This commit only adds documentation comments warning that callbacks registered on a Future object must not re-enter the same Future or its Notifier. It does not change any code behavior, fix a bug, or add safeguards. The change suggests a pre-existing reentrancy hazard exists, but it is left unfixed because the authors considered it hard to address and not worth the effort.
Fix misleading comment on counterparty_commitment_txn_on_chain insert
The comment claimed this insert "isn't useful yet" and was only a safety measure for a watchtower race. In practice it is also used by provide_payment_preimage to look up the commitment number when a preimage arrives after the counterparty commitment tx is confirmed.
AI tools were used in preparing this 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 only changes a code comment to accurately describe why a particular data structure is populated. No program logic, data flow, or behavior was altered. It is purely a documentation fix.
The spec's 25/24 multiplier doesn't always satisfy BIP125's relay requirement of an absolute fee increase at low feerates, while a flat +25 sat/kwu increment falls below the spec's 25/24 rule above 600 sat/kwu. Use max(prev + 25, ceil(prev * 25/24)) for our own RBFs to satisfy both constraints, while still accepting the bare 25/24 rule from counterparties.
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
AI analysis · Low 47/100
This commit fixes how Lightning Dev Kit calculates the minimum fee rate when a user tries to speed up (RBF) a channel funding or splicing transaction. Previously, the code only required the new fee to be 25/24 of the old fee. At very low fee rates that percentage bump is too small to meet Bitcoin's BIP125 network-relay rule, so the replacement transaction could be rejected by the network and never confirm. The fix now uses the larger of (old fee + 25 sat/kwu) and (25/24 of old fee) for transactions this node creates, while still accepting the bare 25/24 rule from peers. This is a protocol-compliance/robustness fix, not a direct theft or remote-exploitation vulnerability.
Lower-priorityutil: add default_value_vec for defaults without LengthReadableby Carla Kirk-Cohen · 5330f9f4 · Mar 31, 2026 · 1 fileMessage 85 · StrongInformational 19Details
Commit message · Carla Kirk-Cohen
util: add default_value_vec for defaults without LengthReadable
Right now, use of `default_value` requires that the struct implements `LengthReadable` itself. When trying to use `default_value` outside of LDK for `Vec<T>`, your code will run into the orphan rule because it does not own the trait `LengthReadable` or the type `Vec`.
There are various ugly workarounds for this (like using `custom`), but wanting to persist a vec with a default value seems like a common enough use case to justify the change.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Informational 19/100
This commit adds a new helper macro called default_value_vec to LDK's serialization toolkit. It lets downstream developers store a list (Vec) of items with a fallback default value, without hitting Rust's 'orphan rule' that normally blocks adding serialization traits to standard types like Vec. The change is purely additive and includes unit tests. There is no indication it fixes a security bug or introduces a vulnerability.
Lower-priorityInclude recent blocks in the `synchronize_listeners`-returned cacheby Matt Corallo · 74e1da3c · Mar 30, 2026 · 2 filesMessage 85 · StrongLow 45Details
Commit message · Matt Corallo
Include recent blocks in the `synchronize_listeners`-returned cache
When `synchronize_listeners` runs, it returns a cache of the headers it needed when doing chain difference-finding. This allows us to ensure that when we start running normally we have all the recent headers in case we need them to reorg.
Sadly, in some cases it was returning a mostly-empty cache. Because it was only being filled during block difference reconciliation it would only get a block around each listener's fork point. Worse, because we were calling `disconnect_blocks` with the cache the cache would assume we were reorging against the main chain and drop blocks we actually want.
Instead, we avoid dropping blocks on `disconnect_blocks` calls and ensure we always add connected blocks to the cache.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Low 45/100
This patch fixes a bug in rust-lightning's initial blockchain synchronization where the header cache returned to callers was often nearly empty. The cache is meant to keep recent block headers so the node can handle chain reorganizations after startup. Because the cache was being incorrectly cleared during synchronization, a node could start normal operation without the recent headers it needs to safely detect and respond to reorgs. This is a correctness/reliability fix in chain-sync logic, not a direct remote-exploitable vulnerability.
Lower-priorityUse the header cache across listeners during initial disconnectby Matt Corallo · 941846aa · Mar 30, 2026 · 1 fileMessage 73 · AdequateInformational 18Details
Commit message · Matt Corallo
Use the header cache across listeners during initial disconnect
In `lightning-blocksync::init::synchronize_listeners`, we may have many listeners we want to do a chain diff on. When doing so, we should make sure we utilize our header cache, rather than querying our chain source for every header we need for each listener.
Here we do so, inserting into the cache as we do chain diffs.
On my node with a bitcoind on localhost, this brings the calculate-differences step of `init::synchronize_listeners` from ~500ms to under 150ms.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 18/100
This commit is a performance optimization for the Lightning Dev Kit's block synchronization code. It makes the software reuse a cache of block headers when comparing chain states across multiple listeners, rather than repeatedly asking the Bitcoin node for the same headers. The change reduces startup sync time from about 500ms to under 150ms. It is not a security fix and does not appear to introduce a meaningful security vulnerability.
Security candidateReturn `BestBlock` when deserializing chain-synced structsby Matt Corallo · 413c937d · Mar 30, 2026 · 11 filesMessage 85 · StrongLow 29Details
Commit message · Matt Corallo
Return `BestBlock` when deserializing chain-synced structs
The deserialization of `ChannelMonitor`, `ChannelManager`, and `OutputSweeper` is implemented for a `(BlockHash, ...)` pair rather than on the object itself. This ensures developers are pushed to think about initial chain sync after deserialization and provides the latest chain sync state conviniently at deserialization-time.
In the previous commit we started storing additional recent block hashes in `BestBlock` for use during initial sync to ensure we can handle reorgs while offline if the chain source loses the reorged-out blocks. Here, we move the deserialization routines to be on a `(BestBlock, ...)` pair instead of `(BlockHash, ...)`, providing access to those recent block hashes at deserialization-time.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
Why it was queued
boot or update path
AI analysis · Low 29/100
This commit changes how Lightning Dev Kit (LDK) deserializes (reloads from disk) important chain-following objects like ChannelMonitor and ChannelManager. Previously, deserialization returned just a single latest block hash paired with the object. Now it returns a BestBlock structure that includes the latest block hash plus a short history of recent block hashes. This is a defensive, API-shaping change intended to make downstream developers handle initial chain sync more safely after a restart, especially if the Bitcoin chain source has lost blocks from a reorganization while the node was offline. It is not a patch for an active exploit; it is a hardening/refactoring change that improves resilience against reorgs during startup.
Lower-priorityReplace `Cache::block_disconnected` with `blocks_disconnected`by Matt Corallo · 8b9ccb64 · Mar 30, 2026 · 2 filesMessage 73 · AdequateInformational 21Details
Commit message · Matt Corallo
Replace `Cache::block_disconnected` with `blocks_disconnected`
In 403dc1a48bb71ae794f6883ae0b760aad44cda39 we converted the `Listen` disconnect semantics to only pass the fork point, rather than each block being disconnected. We did not, however, update the semantics of `lightning-block-sync`'s `Cache` to reduce patch size.
Here we go ahead and do so, dropping `ChainDifference::disconnected_blocks` as well as its no longer needed.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 21/100
This commit is a follow-up code cleanup in rust-lightning's block synchronization module. It changes how the code handles blockchain reorganizations (when the chain temporarily forks and then switches to a different branch). Previously, the code tracked and notified about each individual block that was disconnected; now it only passes the fork point, matching an earlier change made to the main listener interface. The commit removes an internal list of disconnected blocks and updates the cache API accordingly. There is no direct evidence in the commit that this fixes a security vulnerability.
Lower-priorityMake `UnboundedCache` boundedby Matt Corallo · 09e77347 · Mar 30, 2026 · 3 filesMessage 58 · ThinLow 37Details
Commit message · Matt Corallo
Make `UnboundedCache` bounded
In the previous commit we moved to hard-coding `UnboundedCache` in the `lightning-block-sync` interface. This is great, except that its an unbounded cache that can use arbitrary amounts of memory (though never really all that much - its just headers that come in while we're running).
Here we simply limit the size, and while we're at it give it a more generic `HeaderCache` name.
This commit replaces an unbounded memory cache of Bitcoin block headers with a bounded one, limiting it to about one week's worth of headers. The change prevents the cache from growing without limit during long-running operation, which could otherwise consume increasing amounts of memory. It also renames the cache from UnboundedCache to HeaderCache and slightly adjusts how old headers are removed during chain reorganizations.
Lower-priorityDrop the `Cache` trait entirelyby Matt Corallo · 1fe6ef1c · Mar 30, 2026 · 2 filesMessage 68 · AdequateInformational 13Details
Commit message · Matt Corallo
Drop the `Cache` trait entirely
Now that `Cache` is crate-private, there's not actually any reason to have it at all. In a later commit we'll have to reach into its internals a bit, but all within the `lightning-block-sync` crate, so having a trait indirection is somewhat useless.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 13/100
This commit is a routine internal code cleanup in the rust-lightning block synchronization crate. It removes an unused internal Rust trait called `Cache` and replaces its indirection with direct use of a concrete `HeaderCache` struct. There is no change to how data is validated, stored, or exposed to users, and no security-relevant behavior is altered.
AI review queuedConsolidate all the pub aync utils to `native_async`by Matt Corallo · 112f2c52 · Mar 30, 2026 · 12 filesMessage 50 · ThinInformational 15Details
Commit message · Matt Corallo
Consolidate all the pub aync utils to `native_async`
50/100 · ThinMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
Why it was queued
signing or wallet pathsecond-pass: security-sensitive path
AI analysis · Informational 15/100
This commit is a straightforward internal code cleanup: it moves two helper marker traits (MaybeSend and MaybeSync) from one Rust module (async_poll) to another (native_async) and updates all import paths accordingly. There is no change to what the code does, no bug fix, and no security-related behavior change.
AI review queuedFetch blocks from source in parallel during initial syncby Matt Corallo · 0f130eee · Mar 30, 2026 · 1 fileMessage 73 · AdequateInformational 18Details
Commit message · Matt Corallo
Fetch blocks from source in parallel during initial sync
In `init::synchronize_listeners` we may end up spending a decent chunk of our time just fetching block data. Here we parallelize that step across up to 36 blocks at a time.
On my node with bitcoind on localhost, the impact of this is somewhat muted by block deserialization being the bulk of the work, however a networked bitcoind would likely change that. Even still, fetching a batch of 36 blocks in parallel happens on my node in ~615 ms vs ~815ms in serial.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
second-pass: broader security terminology
AI analysis · Informational 18/100
This commit is a performance optimization for the initial block synchronization step in rust-lightning. It fetches blocks in parallel batches of up to 36 instead of one at a time, reducing sync time. There is no indication this change fixes a security vulnerability; it is purely about speed.
AI review queuedPass a `BestBlock` to `init::synchronize_listeners`by Matt Corallo · 2664d599 · Mar 30, 2026 · 4 filesMessage 85 · StrongLow 45Details
Commit message · Matt Corallo
Pass a `BestBlock` to `init::synchronize_listeners`
On restart, LDK expects the chain to be replayed starting from where it was when objects were last serialized. This is fine in the normal case, but if there was a reorg and the node which we were syncing from either resynced or was changed, the last block that we were synced as of might no longer be available. As a result, it becomes impossible to figure out where the fork point is, and thus to replay the chain.
Luckily, changing the block source during a reorg isn't exactly common, but we shouldn't end up with a bricked node.
To address this, `lightning-block-sync` allows the user to pass in `Cache` which can be used to cache recent blocks and thus allow for reorg handling in this case. However, serialization for, and a reasonable default implementation of a `Cache` was never built.
Instead, here, we start taking a different approach. To avoid developers having to persist yet another object, we move `BestBlock` to storing some number of recent block hashes. This allows us to find the fork point with just the serialized state.
In a previous commit, we moved deserialization of various structs to return the `BestBlock` rather than a `BlockHash`. Here we move to actually using it, taking a `BestBlock` in place of `BlockHash` to `init::synchronize_listeners` and walking the `previous_blocks` list to find the fork point rather than relying on the `Cache`.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
Why it was queued
second-pass: broader security terminology
AI analysis · Low 45/100
This commit changes how a Bitcoin Lightning node (LDK) recovers after a restart when the blockchain has split/reorganized. Previously, the node only remembered its last known block hash. If that block was no longer available from the block source after a reorg, the node could get stuck ('bricked'). The fix makes the node keep a short history of recent block hashes inside its stored 'BestBlock' state, so it can find the fork point and replay the chain without relying on an extra cache object. This is a robustness improvement, not a typical exploitable vulnerability.
Lower-priorityAdd `async_poll.rs` to `lightning-block-sync`by Matt Corallo · e68cbb3e · Mar 30, 2026 · 2 filesMessage 68 · AdequateInformational 15Details
Commit message · Matt Corallo
Add `async_poll.rs` to `lightning-block-sync`
In the next commit we'll fetch blocks during initial connection in parallel, which requires a multi-future poller. Here we add a symlink to the existing `lightning` `async_poll.rs` file, making it available in `lightning-block-sync`
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
AI analysis · Informational 15/100
This commit adds a symlink to an existing internal utility file and makes minor build configuration changes. It is purely a code-organization/refactoring step with no security-relevant behavior change visible in the diff.
Lower-prioritySilence "elided lifetime has a name" warnings in no-std lockingby Matt Corallo · cd1b7e78 · Mar 30, 2026 · 1 fileMessage 50 · ThinInformational 15Details
Commit message · Matt Corallo
Silence "elided lifetime has a name" warnings in no-std locking
50/100 · ThinMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
AI analysis · Informational 15/100
This is a minor Rust code cleanup change. It adds explicit lifetime labels to two function return types in the no-std synchronization code to silence compiler warnings. There is no functional change, no security fix, and no behavior change.
Lower-priorityMake the `Cache` trait priv, just use `UnboundedCache` publiclyby Matt Corallo · d76f43af · Mar 30, 2026 · 2 filesMessage 85 · StrongInformational 22Details
Commit message · Matt Corallo
Make the `Cache` trait priv, just use `UnboundedCache` publicly
In the previous commit, we moved to relying on `BestBlock::previous_blocks` to find the fork point in `lightning-block-sync`'s `init::synchronize_listeners`. Here we now drop the `Cache` parameter as we no longer rely on it.
Because we now have no reason to want a persistent `Cache`, we remove the trait from the public interface. However, to keep disconnections reliable we return the `UnboundedCache` we built up during initial sync from `init::synchronize_listeners` which we expect developers to pass to `SpvClient::new`.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Informational 22/100
This commit is a routine API cleanup, not a security fix. It removes a public `Cache` trait from the `lightning-block-sync` crate and forces all users to use the built-in `UnboundedCache`. The change simplifies the code and ensures that block headers collected during initial synchronization are reliably passed forward, avoiding a situation where a user-provided cache could lose headers needed to handle blockchain forks correctly.
Lower-priorityUpdate BestBlock to store ANTI_REORG_DELAY * 2 recent block hashesby Matt Corallo · 51dfcb56 · Mar 30, 2026 · 5 filesMessage 85 · StrongLow 46Details
Commit message · Matt Corallo
Update BestBlock to store ANTI_REORG_DELAY * 2 recent block hashes
On restart, LDK expects the chain to be replayed starting from where it was when objects were last serialized. This is fine in the normal case, but if there was a reorg and the node which we were syncing from either resynced or was changed, the last block that we were synced as of might no longer be available. As a result, it becomes impossible to figure out where the fork point is, and thus to replay the chain.
Luckily, changing the block source during a reorg isn't exactly common, but we shouldn't end up with a bricked node.
To address this, `lightning-block-sync` allows the user to pass in `Cache` which can be used to cache recent blocks and thus allow for reorg handling in this case. However, serialization for, and a reasonable default implementation of a `Cache` was never built.
Instead, here, we start taking a different approach. To avoid developers having to persist yet another object, we move `BestBlock` to storing some number of recent block hashes. This allows us to find the fork point with just the serialized state.
In conjunction with 403dc1a48bb71ae794f6883ae0b760aad44cda39 (which allows us to disconnect blocks without having the stored header), this should allow us to replay chain state after a reorg even if we no longer have access to the top few blocks of the old chain tip.
While we only really need to store `ANTI_REORG_DELAY` blocks (as we generally assume that any deeper reorg won't happen and thus we don't guarantee we handle it correctly), its nice to store a few more to be able to handle more than a six block reorg. While other parts of the codebase may not be entirely robust against such a reorg if the transactions confirmed change out from under us, its entirely possible (and, indeed, common) for reorgs to contain nearly identical transactions.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
AI analysis · Low 46/100
This commit changes how LDK (a Bitcoin Lightning Network library) remembers recent Bitcoin block hashes. Previously, it only remembered the single latest block. After this change, it keeps a small history of the last 12 block hashes. This helps the node recover correctly if the chain reorganizes (a 'reorg') and the block source it was syncing from has changed or resynced. Without this history, the node could get stuck after a restart because it couldn't find the point where the old chain and new chain split. The change is a robustness improvement, not a fix for an active exploit.
Lower-priorityFix flakiness in `test_tor_connect`by Leo Nash · 20e943ef · Mar 30, 2026 · 1 fileMessage 43 · ThinInformational 15Details
Commit message · Leo Nash
Fix flakiness in `test_tor_connect`
Fixes #4519
43/100 · ThinMessage clarity
✓ Descriptive subject✓ Links an issue, advisory, or supporting reference! No meaningful explanatory body
AI analysis · Informational 15/100
This commit only changes a test file to make a flaky test more reliable. It replaces hard-coded Google IP addresses with dynamically resolved addresses, so the test does not break when Google's IP addresses change. There is no change to production code and no security issue.
Even though DevNull discards the bytes, the formatting work (SubstringFormatter, fmt::write, from_utf8) was still being done on every log call. Short-circuit in TestLogger::log via a TypeId check, which monomorphization resolves at compile time.
AI tools were used in preparing this commit.
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 performance optimization for a test-only fuzzing logger. It skips formatting log messages when the output is a special 'DevNull' sink that discards everything anyway. There is no security relevance: no bug is fixed, no memory safety issue is addressed, and no attacker-controlled behavior is changed.
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.
Lower-priorityfuzz: fix coverage report to include library cratesby Joost Jager · 922d9f1f · Mar 30, 2026 · 1 fileMessage 83 · StrongInformational 15Details
Commit message · Joost Jager
fuzz: fix coverage report to include library crates
Since cargo-llvm-cov 0.7.0, only workspace members are instrumented by default. Since the fuzz crate is a standalone workspace, library crates like lightning were not instrumented, and the coverage report was empty.
Add --dep-coverage to instrument the library path dependencies.
This alone is not sufficient for the report: --dep-coverage's report filtering only supports crates.io deps, not path deps (per a TODO in cargo-llvm-cov source). Add --no-default-ignore-filename-regex to include all instrumented code, then use a custom --ignore-filename-regex to exclude unwanted paths (cargo registry, rustup toolchains, fuzz harness).
AI tools were used in preparing this commit.
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Why it was queued
fuzzing or regression evidence
AI analysis · Informational 15/100
This commit fixes a fuzzing coverage report script. It changes which Rust library crates are included when measuring how thoroughly the fuzz tests exercise the code. There is no change to the actual Lightning protocol code, wallet logic, or network behavior, and no security vulnerability is being patched.
Lower-prioritytypes: fix zero conf feature missing `clear_zero_conf`by Philip Kannegaard Hayes · 28f10a54 · Mar 27, 2026 · 1 fileMessage 50 · ThinLow 35Details
Commit message · Philip Kannegaard Hayes
types: fix zero conf feature missing `clear_zero_conf`
50/100 · ThinMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
AI analysis · Low 35/100
This commit fixes a missing 'clear' function for the zero-confirmation channel feature flag in the Lightning Dev Kit. Feature flags are used to negotiate capabilities between Lightning nodes. Without a way to clear this flag, code that needs to remove or reset the zero-confirmation feature could fail to compile or behave unexpectedly, potentially causing misnegotiation of channel types. The fix is small and only adds the missing function.
Lower-prioritySwitch 0FC to production feature bitby Leo Nash · 5ab28b19 · Mar 26, 2026 · 1 fileMessage 45 · ThinLow 27Details
Commit message · Leo Nash
Switch 0FC to production feature bit
45/100 · ThinMessage clarity
✓ Descriptive subject✓ Names a concrete action or component! No meaningful explanatory body
AI analysis · Low 27/100
This commit changes the feature bit used to advertise a new Lightning protocol capability called 'zero-fee commitment anchors' from an experimental/staging number (141) to the official production number (41). Feature bits are how Lightning nodes tell each other which protocol extensions they support during connection setup. The change itself is a protocol compatibility update, not a fix for a vulnerability. However, because it swaps a staging feature for a production one, nodes running older code that only understood the staging bit may fail to recognize the capability in peers running the new code, which could cause interoperability problems or prevent opening of certain channel types.
Lower-priorityUse inline format variables in channel/channelmanager format stringsby Leo Nash · 32a67f80 · Mar 26, 2026 · 2 filesMessage 73 · AdequateInformational 15Details
Commit message · Leo Nash
Use inline format variables in channel/channelmanager format strings
Convert format string arguments to inline `{var}` captures where the argument is a simple identifier (variable or constant). Field accesses, method calls, and expressions remain as positional args.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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 pure code-style cleanup. It changes how some error and log messages are written in Rust so that variables are inserted directly into the format string (e.g., `{var}`) instead of being passed as separate arguments. The wording and behavior of the messages are unchanged, and no security-sensitive logic was modified.