mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-07 22:24:34 +01:00
test: add HaveInputs call-path unit tests
Add unit tests covering `CCoinsViewCache::HaveInputs()`. The tests document that `HaveInputs()` consults the cache first and that a cache miss pulls from the backing view via `GetCoin()`. Co-authored-by: Novo <eunovo9@gmail.com>
This commit is contained in:
@@ -1059,6 +1059,69 @@ BOOST_FIXTURE_TEST_CASE(ccoins_flush_behavior, FlushTest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(ccoins_cache_behavior)
|
||||||
|
{
|
||||||
|
class CCoinsViewSpy final : public CCoinsView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const COutPoint expected;
|
||||||
|
mutable size_t getcoin_calls{0};
|
||||||
|
bool allow_getcoin{true};
|
||||||
|
|
||||||
|
explicit CCoinsViewSpy(const COutPoint& out) : expected{out} {}
|
||||||
|
|
||||||
|
std::optional<Coin> GetCoin(const COutPoint& out) const override
|
||||||
|
{
|
||||||
|
BOOST_CHECK(out == expected);
|
||||||
|
if (!allow_getcoin) {
|
||||||
|
BOOST_FAIL("Base GetCoin should not be called when input is cached");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
++getcoin_calls;
|
||||||
|
return Coin{CTxOut{1, CScript{}}, 1, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HaveCoin(const COutPoint& out) const override
|
||||||
|
{
|
||||||
|
BOOST_CHECK(out == expected);
|
||||||
|
BOOST_FAIL("Base HaveCoin should never be called");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const COutPoint prevout{Txid::FromUint256(m_rng.rand256()), 0};
|
||||||
|
CCoinsViewSpy base{prevout};
|
||||||
|
CCoinsViewCache cache{&base};
|
||||||
|
|
||||||
|
CMutableTransaction mtx;
|
||||||
|
mtx.vin.emplace_back(prevout);
|
||||||
|
const CTransaction tx{mtx};
|
||||||
|
BOOST_CHECK(!tx.IsCoinBase());
|
||||||
|
|
||||||
|
BOOST_CHECK(cache.HaveInputs(tx));
|
||||||
|
BOOST_CHECK_EQUAL(base.getcoin_calls, 1);
|
||||||
|
|
||||||
|
base.allow_getcoin = false;
|
||||||
|
BOOST_CHECK(cache.HaveInputs(tx));
|
||||||
|
BOOST_CHECK(cache.GetCoin(prevout));
|
||||||
|
BOOST_CHECK(!cache.AccessCoin(prevout).IsSpent());
|
||||||
|
BOOST_CHECK(cache.HaveCoin(prevout));
|
||||||
|
BOOST_CHECK_EQUAL(base.getcoin_calls, 1);
|
||||||
|
|
||||||
|
const COutPoint prefilled_prevout{Txid::FromUint256(m_rng.rand256()), 0};
|
||||||
|
cache.AddCoin(prefilled_prevout, Coin{CTxOut{1, CScript{}}, 1, false}, /*possible_overwrite=*/false);
|
||||||
|
BOOST_CHECK(cache.HaveCoinInCache(prefilled_prevout));
|
||||||
|
|
||||||
|
CMutableTransaction prefilled_mtx;
|
||||||
|
prefilled_mtx.vin.emplace_back(prefilled_prevout);
|
||||||
|
const CTransaction prefilled_tx{prefilled_mtx};
|
||||||
|
BOOST_CHECK(!prefilled_tx.IsCoinBase());
|
||||||
|
BOOST_CHECK(cache.HaveInputs(prefilled_tx));
|
||||||
|
|
||||||
|
BOOST_CHECK(cache.SpendCoin(prevout));
|
||||||
|
BOOST_CHECK(!cache.HaveCoinInCache(prevout));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(coins_resource_is_used)
|
BOOST_AUTO_TEST_CASE(coins_resource_is_used)
|
||||||
{
|
{
|
||||||
CCoinsMapMemoryResource resource;
|
CCoinsMapMemoryResource resource;
|
||||||
|
|||||||
Reference in New Issue
Block a user