15#include <boost/test/unit_test.hpp>
21#include <unordered_set>
26std::shared_ptr<ThreadPool> MakeStartedThreadPool()
28 auto pool{std::make_shared<ThreadPool>(
"fetch_test")};
33CBlock CreateBlock() noexcept
35 static constexpr auto NUM_TXS{100};
38 coinbase.
vin.emplace_back();
39 block.
vtx.push_back(MakeTransactionRef(coinbase));
43 for (
const auto i : std::views::iota(1, NUM_TXS)) {
46 tx.
vin.emplace_back(txid, 0);
48 block.
vtx.push_back(MakeTransactionRef(tx));
59 std::unordered_set<Txid, SaltedCoinsCacheHasher> txids{};
60 txids.reserve(block.
vtx.size() - 1);
61 for (
const auto& tx : block.
vtx | std::views::drop(1)) {
62 for (
const auto& in : tx->
vin) {
63 if (txids.contains(in.prevout.hash))
continue;
77 std::unordered_set<Txid, SaltedCoinsCacheHasher> txids{};
78 txids.reserve(block.
vtx.size() - 1);
80 for (
const auto& tx : block.
vtx) {
81 if (tx->IsCoinBase()) {
84 for (
const auto& in : tx->
vin) {
85 const auto& outpoint{in.prevout};
87 const auto& second{cache.
AccessCoin(outpoint)};
101BOOST_AUTO_TEST_SUITE(coinsviewoverlay_tests)
105 const auto block{CreateBlock()};
106 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
107 PopulateView(block,
db);
111 const auto& outpoint{block.
vtx[1]->vin[0].prevout};
117 CheckCache(block, view);
119 for (
const auto& tx : block.
vtx) {
120 for (
const auto& in : tx->
vin) {
133 const auto block{CreateBlock()};
134 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
136 PopulateView(block, main_cache);
139 CheckCache(block, view);
141 const auto& outpoint{block.
vtx[1]->vin[0].prevout};
152 const auto block{CreateBlock()};
153 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
154 PopulateView(block,
db);
157 PopulateView(block, main_cache,
true);
160 for (
const auto& tx : block.
vtx) {
161 for (
const auto& in : tx->
vin) {
174 const auto block{CreateBlock()};
175 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
179 for (
const auto& tx : block.
vtx) {
180 for (
const auto& in : tx->
vin) {
195 coinbase.
vin.emplace_back();
196 block.
vtx.push_back(MakeTransactionRef(coinbase));
197 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
223 const auto block{CreateBlock()};
224 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
226 PopulateView(block, main_cache);
228 std::vector<COutPoint> fetched_inputs;
229 std::unordered_set<Txid, SaltedCoinsCacheHasher> txids;
230 txids.reserve(block.
vtx.size() - 1);
231 for (
const auto& tx : block.
vtx | std::views::drop(1)) {
232 for (
const auto& input : tx->
vin) {
233 if (!txids.contains(input.prevout.hash)) fetched_inputs.push_back(input.prevout);
237 BOOST_REQUIRE_GE(fetched_inputs.size(), 2U);
242 const auto& out_of_order_input{fetched_inputs[1]};
247 CheckCache(block, view);
255 const auto block{CreateBlock()};
256 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
258 PopulateView(block, main_cache);
261 for (
const bool use_flush : {
false,
true,
false}) {
264 CheckCache(block, view);
277BOOST_AUTO_TEST_SUITE(coinsviewoverlay_tests_noworkers)
282 const auto block{CreateBlock()};
283 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
285 PopulateView(block, main_cache);
286 auto thread_pool{std::make_shared<ThreadPool>(
"fetch_none")};
289 CheckCache(block, view);
295 const auto block{CreateBlock()};
296 CCoinsViewDB db{{.path =
"", .cache_bytes = 1_MiB, .memory_only =
true}, {}};
298 PopulateView(block, main_cache);
300 auto thread_pool{std::make_shared<ThreadPool>(
"fetch_intr")};
302 thread_pool->Interrupt();
305 CheckCache(block, view);
constexpr int32_t DEFAULT_PREVOUTFETCH_THREADS
std::vector< CTransactionRef > vtx
CCoinsView that adds a memory cache for transactions to another CCoinsView.
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
void EmplaceCoinInternalDANGER(const COutPoint &outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
virtual void Flush(bool reallocate_cache=true)
Push the modifications applied to this cache to its base and wipe local state.
void SetBestBlock(const uint256 &block_hash)
unsigned int GetCacheSize() const
Size of the cache (in number of transaction outputs).
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
std::optional< Coin > PeekCoin(const COutPoint &outpoint) const override
bool HaveCoin(const COutPoint &outpoint) const override
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
CCoinsView backed by the coin database (chainstate/).
Pure abstract view on the open txout dataset.
An outpoint - a combination of a transaction hash and an index n into its vout.
CTxOut out
unspent transaction output
bool IsSpent() const
Either this coin never existed (see e.g.
CCoinsViewCache subclass that asynchronously fetches most block input prevouts in parallel during Con...
ResetGuard StartFetching(const CBlock &block LIFETIMEBOUND) noexcept
Start fetching inputs from block.
void Flush(bool reallocate_cache=true) override
Push the modifications applied to this cache to its base and wipe local state.
static transaction_identifier FromUint256(const uint256 &id)
constexpr uint256()=default
static const uint256 ZERO
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ipc_tests)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
A mutable version of CTransaction.
Txid GetHash() const
Compute the hash of this CMutableTransaction.
transaction_identifier< false > Txid
Txid commits to all transaction fields except the witness.
BOOST_CHECK_NE(OneL.ToString(), ArrayToString(ZeroArray, 32))