mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-02 09:46:14 +00:00
fuzz: make AddCoins query view for overwrites
In validation, `AddCoins(check_for_overwrite=false)` is only used after BIP30 has already ensured the transaction does not overwrite any unspent outputs in the UTXO view. The coins view fuzz target can call `AddCoins` with arbitrary txids, so using the `check_for_overwrite=false` fast path on non-coinbase transactions may violate the `AddCoin` caller contract and trigger logic errors. Only use `check_for_overwrite=false` when we have first confirmed that none of the outputs are currently unspent. Otherwise, fall back to `check_for_overwrite=true` so `AddCoins` determines overwrites via the view.
This commit is contained in:
parent
b8fa6f0f70
commit
d7e0d510f2
@ -280,19 +280,14 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsViewCache& co
|
||||
// coins.cpp:69: void CCoinsViewCache::AddCoin(const COutPoint &, Coin &&, bool): Assertion `!coin.IsSpent()' failed.
|
||||
return;
|
||||
}
|
||||
bool expected_code_path = false;
|
||||
const int height{int(fuzzed_data_provider.ConsumeIntegral<uint32_t>() >> 1)};
|
||||
const bool possible_overwrite = fuzzed_data_provider.ConsumeBool();
|
||||
try {
|
||||
AddCoins(coins_view_cache, transaction, height, possible_overwrite);
|
||||
expected_code_path = true;
|
||||
} catch (const std::logic_error& e) {
|
||||
if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) {
|
||||
assert(!possible_overwrite);
|
||||
expected_code_path = true;
|
||||
const bool check_for_overwrite{transaction.IsCoinBase() || [&] {
|
||||
for (uint32_t i{0}; i < transaction.vout.size(); ++i) {
|
||||
if (coins_view_cache.PeekCoin(COutPoint{transaction.GetHash(), i})) return true;
|
||||
}
|
||||
}
|
||||
assert(expected_code_path);
|
||||
return fuzzed_data_provider.ConsumeBool();
|
||||
}()}; // We can only skip the check if the current txid has no unspent outputs
|
||||
AddCoins(coins_view_cache, transaction, height, check_for_overwrite);
|
||||
},
|
||||
[&] {
|
||||
(void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user