Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,12 +495,19 @@ class CRegTestParams : public CChainParams
};

m_assumeutxo_data = {
{
{ // For use by unit tests

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe also list the filename here, like in the other cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do that because there are already multiple files that use it (validation_chainstatemanager_tests, validation_chainstate_tests). Seems less likely that the same would happen for fuzz tests.

.height = 110,
.hash_serialized = AssumeutxoHash{uint256S("0x6657b736d4fe4db0cbc796789e812d5dba7f5c143764b1b6905612f1830609d1")},
.nChainTx = 111,
.blockhash = uint256S("0x696e92821f65549c7ee134edceeeeaaa4105647a3c4fd9f298c0aec0ab50425c")
},
{
// For use by fuzz target src/test/fuzz/utxo_snapshot.cpp
.height = 200,
.hash_serialized = AssumeutxoHash{uint256S("0x4f34d431c3e482f6b0d67b64609ece3964dc8d7976d02ac68dd7c9c1421738f2")},
.nChainTx = 201,
.blockhash = uint256S("0x5e93653318f294fb5aa339d00bbf8cf1c3515488ad99412c37608b139ea63b27"),
Comment on lines +506 to +509

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "fuzz: improve utxo_snapshot target" (de71d4d)

Since fuzz test is not deterministic, and doesn't give us an easy way to know hash values here actually allow snapshot to be loaded, it might be good to write a separate regtest generating a an empty chain with height 200 and verifying these hashes.

},
{
// For use by test/functional/feature_assumeutxo.py
.height = 299,
Expand Down
46 changes: 38 additions & 8 deletions src/test/fuzz/utxo_snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,39 @@ FUZZ_TARGET(utxo_snapshot, .init = initialize_chain)

{
AutoFile outfile{fsbridge::fopen(snapshot_path, "wb")};
const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
outfile << Span{file_data};
// Metadata
if (fuzzed_data_provider.ConsumeBool()) {
std::vector<uint8_t> metadata{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
outfile << Span{metadata};
} else {
DataStream data_stream{};
auto msg_start = chainman.GetParams().MessageStart();
int base_blockheight{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, 2 * COINBASE_MATURITY)};
uint256 base_blockhash{g_chain->at(base_blockheight - 1)->GetHash()};
uint64_t m_coins_count{fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(1, 3 * COINBASE_MATURITY)};
SnapshotMetadata metadata{msg_start, base_blockhash, base_blockheight, m_coins_count};
outfile << metadata;
}
// Coins
if (fuzzed_data_provider.ConsumeBool()) {
std::vector<uint8_t> file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
outfile << Span{file_data};
} else {
int height{0};
for (const auto& block : *g_chain) {
auto coinbase{block->vtx.at(0)};
outfile << coinbase->GetHash();
WriteCompactSize(outfile, 1); // number of coins for the hash
WriteCompactSize(outfile, 0); // index of coin
outfile << Coin(coinbase->vout[0], height, /*fCoinBaseIn=*/1);
height++;
}
}
}

const auto ActivateFuzzedSnapshot{[&] {
AutoFile infile{fsbridge::fopen(snapshot_path, "rb")};
auto msg_start = Params().MessageStart();
auto msg_start = chainman.GetParams().MessageStart();
SnapshotMetadata metadata{msg_start};
try {
infile >> metadata;
Expand All @@ -73,16 +99,20 @@ FUZZ_TARGET(utxo_snapshot, .init = initialize_chain)
Assert(*chainman.ActiveChainstate().m_from_snapshot_blockhash ==
*chainman.SnapshotBlockhash());
const auto& coinscache{chainman.ActiveChainstate().CoinsTip()};
int64_t chain_tx{};
for (const auto& block : *g_chain) {
Assert(coinscache.HaveCoin(COutPoint{block->vtx.at(0)->GetHash(), 0}));
const auto* index{chainman.m_blockman.LookupBlockIndex(block->GetHash())};
const auto num_tx{Assert(index)->nTx};
Assert(num_tx == 1);
chain_tx += num_tx;
Assert(index);
Assert(index->nTx == 0);
if (index->nHeight == chainman.GetSnapshotBaseHeight()) {
auto params{chainman.GetParams().AssumeutxoForHeight(index->nHeight)};
Assert(params.has_value());
Assert(params.value().nChainTx == index->nChainTx);
} else {
Assert(index->nChainTx == 0);
}
}
Assert(g_chain->size() == coinscache.GetCacheSize());
Assert(chain_tx == chainman.ActiveTip()->nChainTx);
} else {
Assert(!chainman.SnapshotBlockhash());
Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash);
Expand Down
2 changes: 1 addition & 1 deletion test/functional/feature_assumeutxo.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def expected_error(log_msg="", rpc_details=""):
with open(bad_snapshot_path, 'wb') as f:
f.write(valid_snapshot_contents[:11] + bogus_height.to_bytes(4, "little") + bytes.fromhex(bad_block_hash)[::-1] + valid_snapshot_contents[47:])

msg = f"Unable to load UTXO snapshot: assumeutxo block hash in snapshot metadata not recognized (hash: {bad_block_hash}, height: {bogus_height}). The following snapshot heights are available: 110, 299."
msg = f"Unable to load UTXO snapshot: assumeutxo block hash in snapshot metadata not recognized (hash: {bad_block_hash}, height: {bogus_height}). The following snapshot heights are available: 110, 200, 299."
assert_raises_rpc_error(-32603, msg, node.loadtxoutset, bad_snapshot_path)

self.log.info(" - snapshot file with wrong number of coins")
Expand Down