mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-05 12:39:23 +01:00
cae6d895f8fuzz: add target for CoinsViewOverlay (Andrew Toth)86eda88c8efuzz: move backend mutating block to end of coins_view (Andrew Toth)89824fb27bfuzz: pass coins_view_cache to TestCoinsView in coins_view (Andrew Toth)73e99a5966coins: don't mutate main cache when connecting block (Andrew Toth)67c0d1798ecoins: introduce CoinsViewOverlay (Andrew Toth)69b01af0ebcoins: add PeekCoin() (Andrew Toth) Pull request description: This is a slightly modified version of the first few commits of #31132, which can be merged as an independent change. It has a small benefit on its own, but will help in moving the parent PR forward. When accessing coins via the `CCoinsViewCache`, methods like `GetCoin` can call `FetchCoin` which actually mutate `cacheCoins` internally to cache entries when they are pulled from the backing db. This is generally a performance improvement for single threaded access patterns, but it precludes us from accessing entries in a `CCoinsViewCache` from multiple threads without a lock. Another aspect is that when we use the resettable `CCoinsViewCache` view backed by the main cache for use in `ConnectBlock()`, we will insert entries into the main cache even if the block is determined to be invalid. This is not the biggest concern, since an invalid block requires proof-of-work. But, an attacker could craft multiple invalid blocks to fill the main cache. This would make us `Flush` the cache more often than necessary. Obviously this would be very expensive to do on mainnet. Introduce `CoinsViewOverlay`, a `CCoinsViewCache` subclass that reads coins without mutating the underlying cache via `FetchCoin()`. Add `PeekCoin()` to look up a Coin through a stack of `CCoinsViewCache` layers without populating parent caches. This prevents the main cache from caching inputs pulled from disk for a block that has not yet been fully validated. Once `Flush()` is called on the view, these inputs will be added as spent to `coinsCache` in the main cache via `BatchWrite()`. This is the foundation for async input fetching, where worker threads must not mutate shared state. ACKs for top commit: l0rinc: ACKcae6d895f8sipa: reACKcae6d895f8sedited: Re-ACKcae6d895f8willcl-ark: ACKcae6d895f8vasild: Cursory ACKcae6d895f8ryanofsky: Code review ACKcae6d895f8. PR is basically back to the form I had acked the first time, implementing `PeekCoin()` by calling `GetCoin()`. This is not ideal because `PeekCoin()` is not supposed to modify caches and `GetCoin()` does that, but it at least avoids problems of the subsequent approach tried where `GetCoin()` calls `PeekCoin` and would result in bugs when subclasses implement `GetCoin` forgetting to override `PeekCoin`. Hopefully #34124 can clean all of this by making relevant methods pure virtual. Tree-SHA512: a81a98e60ca9e47454933ad879840cc226cb3b841bc36a4b746c34b350e07c546cdb5ddc55ec1ff66cf65d1ec503d22201d3dc12d4e82a8f4d386ccc52ba6441