|
1 | | -// Copyright (c) 2020-2022 The Bitcoin Core developers |
| 1 | +// Copyright (c) 2020-present The Bitcoin Core developers |
2 | 2 | // Distributed under the MIT software license, see the accompanying |
3 | 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | 4 |
|
@@ -42,11 +42,12 @@ void initialize_coins_view() |
42 | 42 | static const auto testing_setup = MakeNoLogFileContext<>(); |
43 | 43 | } |
44 | 44 |
|
45 | | -void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend_coins_view) |
| 45 | +void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend_coins_view, bool is_db) |
46 | 46 | { |
47 | 47 | bool good_data{true}; |
48 | 48 |
|
49 | 49 | CCoinsViewCache coins_view_cache{&backend_coins_view, /*deterministic=*/true}; |
| 50 | + if (is_db) coins_view_cache.SetBestBlock(uint256::ONE); |
50 | 51 | COutPoint random_out_point; |
51 | 52 | Coin random_coin; |
52 | 53 | CMutableTransaction random_mutable_transaction; |
@@ -85,7 +86,10 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend |
85 | 86 | (void)coins_view_cache.Sync(); |
86 | 87 | }, |
87 | 88 | [&] { |
88 | | - coins_view_cache.SetBestBlock(ConsumeUInt256(fuzzed_data_provider)); |
| 89 | + uint256 best_block{ConsumeUInt256(fuzzed_data_provider)}; |
| 90 | + // Set best block hash to non-null to satisfy the assertion in CCoinsViewDB::BatchWrite(). |
| 91 | + if (is_db && best_block.IsNull()) best_block = uint256::ONE; |
| 92 | + coins_view_cache.SetBestBlock(best_block); |
89 | 93 | }, |
90 | 94 | [&] { |
91 | 95 | Coin move_to; |
@@ -153,7 +157,11 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend |
153 | 157 | bool expected_code_path = false; |
154 | 158 | try { |
155 | 159 | auto cursor{CoinsViewCacheCursor(usage, sentinel, coins_map, /*will_erase=*/true)}; |
156 | | - coins_view_cache.BatchWrite(cursor, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock()); |
| 160 | + uint256 best_block{coins_view_cache.GetBestBlock()}; |
| 161 | + if (fuzzed_data_provider.ConsumeBool()) best_block = ConsumeUInt256(fuzzed_data_provider); |
| 162 | + // Set best block hash to non-null to satisfy the assertion in CCoinsViewDB::BatchWrite(). |
| 163 | + if (is_db && best_block.IsNull()) best_block = uint256::ONE; |
| 164 | + coins_view_cache.BatchWrite(cursor, best_block); |
157 | 165 | expected_code_path = true; |
158 | 166 | } catch (const std::logic_error& e) { |
159 | 167 | if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) { |
@@ -207,7 +215,7 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend |
207 | 215 |
|
208 | 216 | { |
209 | 217 | std::unique_ptr<CCoinsViewCursor> coins_view_cursor = backend_coins_view.Cursor(); |
210 | | - assert(!coins_view_cursor); |
| 218 | + assert(is_db == !!coins_view_cursor); |
211 | 219 | (void)backend_coins_view.EstimateSize(); |
212 | 220 | (void)backend_coins_view.GetBestBlock(); |
213 | 221 | (void)backend_coins_view.GetHeadBlocks(); |
@@ -298,5 +306,17 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view) |
298 | 306 | { |
299 | 307 | FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; |
300 | 308 | CCoinsView backend_coins_view; |
301 | | - TestCoinsView(fuzzed_data_provider, backend_coins_view); |
| 309 | + TestCoinsView(fuzzed_data_provider, backend_coins_view, /*is_db=*/false); |
| 310 | +} |
| 311 | + |
| 312 | +FUZZ_TARGET(coins_view_db, .init = initialize_coins_view) |
| 313 | +{ |
| 314 | + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; |
| 315 | + auto db_params = DBParams{ |
| 316 | + .path = "", |
| 317 | + .cache_bytes = 1_MiB, |
| 318 | + .memory_only = true, |
| 319 | + }; |
| 320 | + CCoinsViewDB coins_db{std::move(db_params), CoinsViewOptions{}}; |
| 321 | + TestCoinsView(fuzzed_data_provider, coins_db, /*is_db=*/true); |
302 | 322 | } |
0 commit comments