| 17 | //! at the expected utilization thresholds, first with *no* mempool head-room, |
| 18 | //! then with additional mempool head-room. |
| 19 | BOOST_AUTO_TEST_CASE(getcoinscachesizestate) |
| 20 | { |
| 21 | Chainstate& chainstate{m_node.chainman->ActiveChainstate()}; |
| 22 | |
| 23 | LOCK(::cs_main); |
| 24 | CCoinsViewCache& view{chainstate.CoinsTip()}; |
| 25 | |
| 26 | // Sanity: an empty cache should be ≲ 1 chunk (~ 256 KiB). |
| 27 | BOOST_CHECK_LT(view.DynamicMemoryUsage() / (256 * 1024.0), 1.1); |
| 28 | |
| 29 | constexpr size_t MAX_COINS_BYTES{8_MiB}; |
| 30 | constexpr size_t MAX_MEMPOOL_BYTES{4_MiB}; |
| 31 | constexpr size_t MAX_ATTEMPTS{50'000}; |
| 32 | |
| 33 | // Run the same growth-path twice: first with 0 head-room, then with extra head-room |
| 34 | for (size_t max_mempool_size_bytes : {size_t{0}, MAX_MEMPOOL_BYTES}) { |
| 35 | const int64_t full_cap{int64_t(MAX_COINS_BYTES + max_mempool_size_bytes)}; |
| 36 | const int64_t large_cap{LargeCoinsCacheThreshold(full_cap)}; |
| 37 | |
| 38 | // OK → LARGE |
| 39 | auto state{chainstate.GetCoinsCacheSizeState(MAX_COINS_BYTES, max_mempool_size_bytes)}; |
| 40 | for (size_t i{0}; i < MAX_ATTEMPTS && int64_t(view.DynamicMemoryUsage()) <= large_cap; ++i) { |
| 41 | BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::OK); |
| 42 | AddTestCoin(m_rng, view); |
| 43 | state = chainstate.GetCoinsCacheSizeState(MAX_COINS_BYTES, max_mempool_size_bytes); |
| 44 | } |
| 45 | |
| 46 | // LARGE → CRITICAL |
| 47 | for (size_t i{0}; i < MAX_ATTEMPTS && int64_t(view.DynamicMemoryUsage()) <= full_cap; ++i) { |
| 48 | BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::LARGE); |
| 49 | AddTestCoin(m_rng, view); |
| 50 | state = chainstate.GetCoinsCacheSizeState(MAX_COINS_BYTES, max_mempool_size_bytes); |
| 51 | } |
| 52 | BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::CRITICAL); |
| 53 | } |
| 54 | |
| 55 | // Default thresholds (no explicit limits) permit many more coins. |
| 56 | for (int i{0}; i < 1'000; ++i) { |
| 57 | AddTestCoin(m_rng, view); |
| 58 | BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(), CoinsCacheSizeState::OK); |
| 59 | } |
| 60 | |
| 61 | // CRITICAL → OK via Flush |
| 62 | BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(MAX_COINS_BYTES, /*max_mempool_size_bytes=*/0), CoinsCacheSizeState::CRITICAL); |
| 63 | view.SetBestBlock(m_rng.rand256()); |
| 64 | view.Flush(); |
| 65 | BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(MAX_COINS_BYTES, /*max_mempool_size_bytes=*/0), CoinsCacheSizeState::OK); |
| 66 | } |
| 67 | |
| 68 | BOOST_AUTO_TEST_SUITE_END() |
nothing calls this directly
no test coverage detected