5 #include <chainparams.h> 29 #include <boost/test/unit_test.hpp> 43 std::vector<Chainstate*> chainstates;
50 chainstates.push_back(&c1);
54 auto all = manager.
GetAll();
55 BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
64 auto exp_tip = c1.m_chain.Tip();
71 const uint256 snapshot_blockhash = active_tip->GetBlockHash();
73 chainstates.push_back(&c2);
75 1 << 23,
true,
false);
78 c2.InitCoinsCache(1 << 23);
91 auto all2 = manager.
GetAll();
92 BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
116 size_t max_cache = 10000;
120 std::vector<Chainstate*> chainstates;
125 chainstates.push_back(&c1);
128 c1.InitCoinsCache(1 << 23);
129 manager.MaybeRebalanceCaches();
139 chainstates.push_back(&c2);
141 1 << 23,
true,
false);
154 c2.InitCoinsCache(1 << 23);
155 manager.MaybeRebalanceCaches();
174 .coins_db_in_memory =
false,
175 .block_tree_db_in_memory =
false,
194 size_t initial_total_coins{100};
201 size_t total_coins{0};
222 constexpr
int snapshot_height = 110;
225 initial_total_coins += 10;
301 int chains_tested{0};
304 BOOST_TEST_MESSAGE(
"Checking coins in " << chainstate->ToString());
310 size_t total_coins{0};
327 constexpr
size_t new_coins{100};
332 size_t coins_in_active{0};
333 size_t coins_in_background{0};
334 size_t coins_missing_from_background{0};
337 BOOST_TEST_MESSAGE(
"Checking coins in " << chainstate->ToString());
343 if (coinscache.HaveCoin(op)) {
344 (is_background ? coins_in_background : coins_in_active)++;
345 }
else if (is_background) {
346 coins_missing_from_background++;
362 loaded_snapshot_blockhash);
363 return std::make_tuple(&validation_chainstate, &snapshot_chainstate);
374 BOOST_TEST_MESSAGE(
"Simulating node restart");
378 cs->ForceFlushStateToDisk();
383 chainman.ResetChainstates();
392 const BlockManager::Options blockman_opts{
393 .chainparams = chainman_opts.chainparams,
395 .notifications = chainman_opts.notifications,
414 this->SetupSnapshot();
435 const int expected_assumed_valid{20};
436 const int last_assumed_valid_idx{111};
437 const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
448 auto reload_all_block_indexes = [&]() {
455 cs->ClearBlockIndexCandidates();
464 reload_all_block_indexes();
473 if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
476 index->m_chain_tx_count = 0;
482 if (i == (assumed_valid_start_idx - 1)) {
483 validated_tip = index;
486 if (i == last_assumed_valid_idx - 1) {
487 assumed_base = index;
493 return chainman.ActivateExistingSnapshot(*assumed_base->phashBlock));
509 reload_all_block_indexes();
566 this->SetupSnapshot();
576 auto all_chainstates = chainman.
GetAll();
598 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
601 this->LoadVerifyActivateChainstate();
604 LOCK(chainman_restarted.GetMutex());
606 BOOST_CHECK(chainman_restarted.IsSnapshotActive());
607 BOOST_CHECK(!chainman_restarted.IsSnapshotValidated());
609 BOOST_CHECK_EQUAL(chainman_restarted.ActiveTip()->GetBlockHash(), snapshot_tip_hash);
614 "Ensure we can mine blocks on top of the initialized snapshot chainstate");
617 LOCK(chainman_restarted.GetMutex());
623 if (
cs != &chainman_restarted.ActiveChainstate()) {
632 this->SetupSnapshot();
650 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
661 auto all_chainstates = chainman.
GetAll();
666 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
680 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
684 this->LoadVerifyActivateChainstate();
705 "Ensure we can mine blocks on top of the \"new\" IBD chainstate");
715 auto chainstates = this->SetupSnapshot();
716 Chainstate& validation_chainstate = *std::get<0>(chainstates);
724 return validation_chainstate.
CoinsTip());
728 badcoin.out.scriptPubKey.assign(m_rng.randbits(6), 0);
737 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
741 auto all_chainstates = chainman.GetAll();
754 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
758 this->LoadVerifyActivateChainstate();
772 "Ensure we can mine blocks on top of the \"new\" IBD chainstate");
781 template <
typename Options>
783 const std::vector<const char*>&
args)
785 const auto argv{
Cat({
"ignore"},
args)};
798 auto get_opts = [&](
const std::vector<const char*>&
args) {
803 .notifications = notifications};
807 auto get_valid_opts = [&](
const std::vector<const char*>&
args) {
814 BOOST_CHECK(!get_valid_opts({}).assumed_valid_block);
820 std::string assume_valid{
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"};
824 BOOST_CHECK(!get_opts({
"-assumevalid=01234567890123456789012345678901234567890123456789012345678901234"}));
827 BOOST_CHECK(!get_valid_opts({}).minimum_chain_work);
832 std::string minimum_chainwork{
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"};
836 BOOST_CHECK(!get_opts({
"-minimumchainwork=01234567890123456789012345678901234567890123456789012345678901234"}));
std::shared_ptr< const CTransaction > CTransactionRef
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
fs::path path
Location in the filesystem where leveldb data will be stored.
kernel::CacheSizes m_kernel_cache_sizes
std::unique_ptr< node::Warnings > warnings
Manages all the node warnings.
util::SignalInterrupt * shutdown_signal
Interrupt object used to track whether node shutdown was requested.
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
bool m_block_tree_db_in_memory
util::Result< Options > SetOptsFromArgs(ArgsManager &args_man, Options opts, const std::vector< const char *> &args)
Helper function to parse args into args_man and return the result of applying them to opts...
ArgsManager m_args
Test-specific arguments and settings.
std::optional< uint256 > ReadSnapshotBaseBlockhash(fs::path chaindir)
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
ChainstateManager & SimulateNodeRestart()
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::atomic< int > exit_status
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
std::tuple< Chainstate *, Chainstate * > SetupSnapshot()
int Height() const
Return the maximal height in the chain.
CTxOut out
unspent transaction output
const CChainParams & chainparams
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
std::vector< CTransactionRef > m_coinbase_txns
An options struct for ChainstateManager, more ergonomically referred to as ChainstateManager::Options...
bool ParseParameters(int argc, const char *const argv[], std::string &error)
size_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
std::optional< fs::path > FindSnapshotChainstateDir(const fs::path &data_dir)
Return a path to the snapshot-based chainstate dir, if one exists.
util::Result< void > ApplyArgsManOptions(const ArgsManager &args, BlockManager::Options &opts)
CChain m_chain
The current chain of blockheaders we consult and build on.
static const unsigned int MAX_DISCONNECTED_TX_POOL_BYTES
Maximum bytes for transactions to store for processing during reorg.
consteval auto _(util::TranslatedLiteral str)
Non-refcounted RAII wrapper for FILE*.
void SetTip(CBlockIndex &block)
Set/initialize a chain with a given tip.
arith_uint256 UintToArith256(const uint256 &a)
void SetBestBlock(const uint256 &hashBlock)
uint256 GetBlockHash() const
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
bool DisconnectTip(BlockValidationState &state, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
bool IsSnapshotActive() const
Chainstate stores and provides an API to update our local knowledge of the current best chain...
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_FIXTURE_TEST_CASE(chainstatemanager, TestChain100Setup)
Basic tests for ChainstateManager.
uint64_t m_chain_tx_count
(memory only) Number of transactions in the chain up to and including this block. ...
fs::path GetBlocksDirPath() const
Get blocks directory path.
bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
BOOST_AUTO_TEST_SUITE_END()
static std::optional< uint256 > FromHex(std::string_view str)
static const uint256 ZERO
void mineBlocks(int num_blocks)
Mine a series of new blocks on the active chain.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
#define ASSERT_DEBUG_LOG(message)
An outpoint - a combination of a transaction hash and an index n into its vout.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
A base class defining functions for notifying about certain kernel events.
size_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
DisconnectedBlockTransactions.
Chainstate &InitializeChainstate(CTxMemPool *mempool) EXCLUSIVE_LOCKS_REQUIRED(std::vector< Chainstate * GetAll)()
Instantiate a new chainstate.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
256-bit unsigned big integer.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
const CBlockIndex *SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(std::set< CBlockIndex *, node::CBlockIndexWorkComparator > setBlockIndexCandidates
The base of the snapshot this chainstate was created from.
#define BOOST_CHECK_EQUAL(v1, v2)
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
static transaction_identifier FromUint256(const uint256 &id)
static bool CreateAndActivateUTXOSnapshot(TestingSetup *fixture, F malleation=NoMalleation, bool reset_chainstate=false, bool in_memory_chainstate=false)
Create and activate a UTXO snapshot, optionally providing a function to malleate the snapshot...
std::unique_ptr< KernelNotifications > notifications
Issues blocking calls about sync status, errors and warnings.
void ResetBlockSequenceCounters() EXCLUSIVE_LOCKS_REQUIRED(
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Application-specific storage settings.
bilingual_str ErrorString(const Result< T > &result)
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
std::optional< uint256 > SnapshotBlockhash() const
CCoinsView that adds a memory cache for transactions to another CCoinsView.
static bool exists(const path &p)
std::optional< AssumeutxoData > AssumeutxoForHeight(int height) const
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
std::function< bool()> shutdown_request
Function to request a shutdown.
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
std::unique_ptr< ChainstateManager > chainman
Testing setup that configures a complete environment.
bool IsSnapshotValidated() const EXCLUSIVE_LOCKS_REQUIRED(
Is there a snapshot in use and has it been fully validated?
#define Assert(val)
Identity function.
#define BOOST_CHECK(expr)
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.