AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 60 Bitcoin

coins: fix `cachedCoinsUsage` accounting to prevent underflow

Public commit record

What the developer wrote

Authored by Lőrinc

95/100 · Strong
coins: fix `cachedCoinsUsage` accounting to prevent underflow

Move the `cachedCoinsUsage` subtract in `AddCoin()` to after the `possible_overwrite` check.
Previously a throw before assignment decremented the counter without changing the entry, which corrupted accounting and later underflowed.

In `Flush()`, reset `cachedCoinsUsage` to `0` only when `BatchWrite()` succeeds and `cacheCoins` is actually cleared. In production `BatchWrite()` returns `true`, so this mostly affects tests. On failure, leave the counter unchanged to keep it in sync with the cache.

The existing `Flush()` workaround in fuzzing was also removed now that the source of the problem was fixed, so the fuzzer no longer needs `coins_view_cache.Flush()` to realign `cachedCoinsUsage` after an exception.
Replace the prior `expected_code_path` tracking with direct assertions. The role of the variable was to verify that code execution follows only expected paths, either successful addition, or if it's an exception, the message is verified and checked that overwrite was disallowed.

With these changes the counter stays consistent across success and exception paths, so we can finally remove the `UBSan` suppressions for `CCoinsViewCache` that were masking the issue.

Included a unit test as well, attempting to add a different coin to the same outpoint without allowing overwrites and make sure it throws.
We use `SelfTest()` to validates accounting, and check that the cache remains usable.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Co-authored-by: w0xlt <woltx@protonmail.com>
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification
The short version

What changed, and why it matters

This commit fixes an internal accounting bug in Bitcoin Core's coin cache. When adding a coin to a cache slot that was already occupied, the program could subtract memory usage before checking whether the operation was allowed. If the operation then threw an exception, the subtraction had already happened but the coin was not actually replaced, causing the internal memory counter to drift and eventually underflow (wrap around to a huge number). The fix moves the subtraction to after the safety check, and only resets the counter when the cache is successfully flushed. It also removes UBSan suppressions that were hiding the underflow and adds a unit test.

Recommended action

Treat as a defensive correctness fix with potential denial-of-service relevance. Review whether any reachable code path could trigger the exception and underflow in production nodes; if reachable, assess for memory accounting corruption or node instability. Apply the patch and ensure UBSan/ASan CI no longer needs the removed suppressions.

Security signals we found

01

Integer underflow in memory accounting counter (cachedCoinsUsage)

02

Logic error exception path corrupts cache accounting before safety check

03

UBSan suppressions removed after root-cause fix

04

Fuzzing workaround removed because underlying bug is fixed

05

Unit test added for exception-path accounting integrity

Risk score

Why this scored 60/100

Our methodology →
Potential impact 18/30
Exploitability 8/25
Stealth signal 10/15
Affected reach 12/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.