Skip to content

coins: split coins view cache and storage contracts#158

Draft
l0rinc wants to merge 6 commits into
masterfrom
l0rinc/coins-view-interface-split
Draft

coins: split coins view cache and storage contracts#158
l0rinc wants to merge 6 commits into
masterfrom
l0rinc/coins-view-interface-split

Conversation

@l0rinc
Copy link
Copy Markdown
Owner

@l0rinc l0rinc commented May 3, 2026

Problem

CCoinsView currently exposes coin lookup, cache flushing, persistent storage traversal, storage sizing, and backend switching through the same base interface.
This makes cache overlays, mempool views, error-catching views, and database-backed storage advertise capabilities that only some of them naturally own.
It also leaves the cache backend contract implicit: a cache must read misses and flush writes through the same state object, not through separate reader and writer instances.

Fix

This PR narrows CCoinsView to coin lookup and best-block reads, introduces CCoinsViewStorage for persistent storage traversal and sizing, and introduces CCoinsViewCacheBackend for same-object cache backends that can also receive BatchWrite.

Backend switching moves down to CCoinsViewCache, the generic CCoinsViewBacked forwarding adapter is removed, and cache construction now takes live backend references.
The stack also removes the stale CTxMemPool::check const_cast by making its cache-populating read side effect explicit in the parameter type.

GetCoin and PeekCoin intentionally remain separate because CoinsViewOverlay still needs a non-caching lookup path.
A further split that lets temporary mempool overlays be read-only cache backends would be a natural follow-up, but this PR keeps the current flush behavior unchanged.

l0rinc added 6 commits May 4, 2026 21:09
The coins view fuzz helper currently derives persistent-storage coverage from the same backend pointer it mutates with cache backend switching, and it detects DB behavior with a `dynamic_cast`.

Give the helper an explicit DB best-block policy and use its active backend only for reader and cache behavior.
Move DB cursor, size, and head-block checks into the DB-specific fuzz target, where the storage object is stable.

This records the fuzz behavior change before the storage interface split, so the next commit can remove storage methods from the generic reader without also changing what the fuzz target is trying to prove.
The generic coins reader exposes persistent storage iteration and sizing hooks that cache and backed views do not naturally support.

Introduce `CCoinsViewStorage` for cursor, head-block, and size users, and move coinstats, RPC, snapshot validation, and remaining fuzz callers to request that storage contract directly.

`CCoinsView` now keeps coin lookup, best-block reads, and batch writes, while cache and backed adapters stop providing storage-only fallbacks.

`CCoinsViewStorage` deliberately repeats `GetBestBlock` so storage traversal can use the associated block hash without depending on the coin lookup interface.
`SetBackend` only mutates the temporary backend of `CCoinsViewCache`, but the setter lived on every generic backed view.

Make `CCoinsViewCache` own its backend pointer directly and keep backend switching on the cache type that actually uses it.

This leaves other backed adapters unchanged for now while removing the split where `CCoinsViewBacked` stored the pointer and `CCoinsViewCache` exposed the mutation.

`CCoinsViewBacked` hides different fallback contracts behind one broad forwarding base.

Remove the generic backed adapter and let each remaining adapter spell out its forwarding directly. `CCoinsViewCache` already owns the mutable backend slot; `CCoinsViewMemPool` and `CCoinsViewErrorCatcher` now keep their own base pointers with reference constructors.

This keeps mempool lookup behavior unchanged: `GetCoin` can see mempool outputs, while `PeekCoin`, `HaveCoin`, best-block reads, and batch writes still fall through to the base view.
`CCoinsViewCache` always needs a live backend view, and backend switching already uses a reference.

Make cache construction take `CCoinsView&`, so the non-null backend contract is part of the signature instead of a pointer that is immediately asserted.

`CTxMemPool::check` already built a duplicate cache from `active_coins_tip` and allowed cache-populating reads through a `const_cast`. Make that parameter mutable and build the duplicate through the same backend-reference contract, removing the cast and making the caching side effect explicit before the backend capability is narrowed further.
`BatchWrite` is only needed by objects that can receive cache flushes, but keeping it on `CCoinsView` makes every reader advertise a write target.

Introduce `CCoinsViewCacheBackend` as the same-object contract for cache backends: callers get the reader surface from `CCoinsView`, and caches require a backend that also accepts batch writes.

This keeps the writer requirement explicit without passing separate reader and writer instances, and without runtime detection or cast-based constructor plumbing.

Cache-on-cache construction sites keep named `CCoinsViewCacheBackend&` bindings where needed to select the backend constructor without casts; direct construction from a `CCoinsViewCache` lvalue would otherwise bind to the deleted copy constructor.
Constructing a cache on top of another cache currently needs a named `CCoinsViewCacheBackend&` reference, because direct construction from a `CCoinsViewCache` lvalue would otherwise prefer the deleted copy constructor.

Add a non-const parent-cache constructor that delegates through the same backend initialization path, using private tag dispatch to avoid cast-based disambiguation. This keeps copy construction deleted while allowing `CCoinsViewCache child{parent};` to spell the layering intent directly.

Update the test helper to inherit the base constructors and add the same non-const parent-cache path for cache-test layers.
@l0rinc l0rinc force-pushed the l0rinc/coins-view-interface-split branch from 8997e08 to 0e3f171 Compare May 4, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant