Problem
The current coins database read-error handling adds unnecessary complexity to the critical path:
CCoinsViewErrorCatchersits between the cache and database views, wrapping every read operation with a generic error handlerExecuteBackedWrapperadds another function call layer with lambda captures on each database read- Uses
std::vector<std::function<void()>>for callbacks when there’s only ever one callback registered - The error callback is set after database initialization rather than during construction (requiring a
cs_mainlock)
This adds unnecessary stack depth and bookkeeping overhead on every coins database read operation (GetCoin). Also note that CCoinsViewDB::HaveCoin isn’t even called from production code as far as I can tell.
Context
This is part of ongoing coins caching cleanup efforts like #34124, #33866, #33018, and #33512.
Fix
This PR collapses the CCoinsViewErrorCatcher layer entirely and moves error handling directly into CCoinsViewDB:
- Remove
ExecuteBackedWrapperandCCoinsViewErrorCatcher, placing try-catch blocks directly inCCoinsViewDB::GetCoinandCCoinsViewDB::HaveCoin - Replace
std::vector<std::function<void()>>with a singlestd::function<void()>member, initialized in the constructor - The read error callback is now passed to
Chainstate::InitCoinsDBand forwarded toCCoinsViewDBconstructor
A new test is also added to reproduce the behavior in case of database corruption. It’s added as a first commit to demonstrate that the behavior stays unchanged.