Skip to content

Commit

Permalink
fuzz: add a target for the coins database
Browse files Browse the repository at this point in the history
It reuses the logic from the `coins_view` target, except it uses an
in-memory CCoinsViewDB as the backend.

Note `CCoinsViewDB` will assert the best block hash is never null, so we
slightly modify the coins_view fuzz logic to take care of this.
  • Loading branch information
darosior committed May 29, 2024
1 parent 48e5b0d commit e79784e
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/test/fuzz/coins_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ void initialize_coins_view()
g_setup = testing_setup.get();
}

void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend_coins_view)
void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend_coins_view, bool is_db = false)
{
bool good_data{true};

CCoinsViewCache coins_view_cache{&backend_coins_view, /*deterministic=*/true};
if (is_db) coins_view_cache.SetBestBlock(uint256::ONE);
COutPoint random_out_point;
Coin random_coin;
CMutableTransaction random_mutable_transaction;
Expand Down Expand Up @@ -87,7 +88,9 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend
(void)coins_view_cache.Sync();
},
[&] {
coins_view_cache.SetBestBlock(ConsumeUInt256(fuzzed_data_provider));
uint256 best_block{ConsumeUInt256(fuzzed_data_provider)};
if (is_db && best_block.IsNull()) best_block = uint256::ONE;
coins_view_cache.SetBestBlock(best_block);
},
[&] {
Coin move_to;
Expand Down Expand Up @@ -147,7 +150,10 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend
}
bool expected_code_path = false;
try {
coins_view_cache.BatchWrite(coins_map, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock());
uint256 best_block{coins_view_cache.GetBestBlock()};
if (fuzzed_data_provider.ConsumeBool()) best_block = ConsumeUInt256(fuzzed_data_provider);
if (is_db && best_block.IsNull()) best_block = uint256::ONE;
coins_view_cache.BatchWrite(coins_map, best_block);
expected_code_path = true;
} catch (const std::logic_error& e) {
if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) {
Expand Down Expand Up @@ -203,7 +209,7 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend

{
std::unique_ptr<CCoinsViewCursor> coins_view_cursor = backend_coins_view.Cursor();
assert(!coins_view_cursor);
assert(is_db ? !!coins_view_cursor : !coins_view_cursor);
(void)backend_coins_view.EstimateSize();
(void)backend_coins_view.GetBestBlock();
(void)backend_coins_view.GetHeadBlocks();
Expand Down Expand Up @@ -296,3 +302,15 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view)
CCoinsView backend_coins_view;
TestCoinsView(fuzzed_data_provider, backend_coins_view);
}

FUZZ_TARGET(coins_db, .init = initialize_coins_view)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
auto db_params = DBParams{
.path = "", // Memory only.
.cache_bytes = 1 << 20, // 1MB.
.memory_only = true,
};
CCoinsViewDB coins_db{std::move(db_params), CoinsViewOptions{}};
TestCoinsView(fuzzed_data_provider, coins_db, /* is_db = */ true);
}

0 comments on commit e79784e

Please sign in to comment.