5 #include <chainparams.h> 26 #include <boost/test/unit_test.hpp> 32 BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests,
TestingSetup)
40 std::vector<Chainstate*> chainstates;
47 chainstates.push_back(&c1);
51 auto all = manager.
GetAll();
52 BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
61 auto exp_tip = c1.m_chain.Tip();
68 const uint256 snapshot_blockhash = active_tip->GetBlockHash();
70 chainstates.push_back(&c2);
72 1 << 23,
true,
false);
75 c2.InitCoinsCache(1 << 23);
88 auto all2 = manager.
GetAll();
89 BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
113 size_t max_cache = 10000;
117 std::vector<Chainstate*> chainstates;
122 chainstates.push_back(&c1);
125 c1.InitCoinsCache(1 << 23);
126 manager.MaybeRebalanceCaches();
136 chainstates.push_back(&c2);
138 1 << 23,
true,
false);
151 c2.InitCoinsCache(1 << 23);
152 manager.MaybeRebalanceCaches();
171 .coins_db_in_memory =
false,
172 .block_tree_db_in_memory =
false,
191 size_t initial_total_coins{100};
198 size_t total_coins{0};
219 constexpr
int snapshot_height = 110;
222 initial_total_coins += 10;
298 int chains_tested{0};
301 BOOST_TEST_MESSAGE(
"Checking coins in " << chainstate->ToString());
307 size_t total_coins{0};
324 constexpr
size_t new_coins{100};
329 size_t coins_in_active{0};
330 size_t coins_in_background{0};
331 size_t coins_missing_from_background{0};
334 BOOST_TEST_MESSAGE(
"Checking coins in " << chainstate->ToString());
340 if (coinscache.HaveCoin(op)) {
341 (is_background ? coins_in_background : coins_in_active)++;
342 }
else if (is_background) {
343 coins_missing_from_background++;
359 loaded_snapshot_blockhash);
360 return std::make_tuple(&validation_chainstate, &snapshot_chainstate);
371 BOOST_TEST_MESSAGE(
"Simulating node restart");
375 cs->ForceFlushStateToDisk();
380 chainman.ResetChainstates();
389 const BlockManager::Options blockman_opts{
390 .chainparams = chainman_opts.chainparams,
392 .notifications = chainman_opts.notifications,
406 this->SetupSnapshot();
427 const int expected_assumed_valid{20};
428 const int last_assumed_valid_idx{111};
429 const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
440 auto reload_all_block_indexes = [&]() {
447 cs->ClearBlockIndexCandidates();
456 reload_all_block_indexes();
465 if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
468 index->m_chain_tx_count = 0;
474 if (i == (assumed_valid_start_idx - 1)) {
475 validated_tip = index;
478 if (i == last_assumed_valid_idx - 1) {
479 assumed_base = index;
485 return chainman.ActivateExistingSnapshot(*assumed_base->phashBlock));
501 reload_all_block_indexes();
558 this->SetupSnapshot();
568 auto all_chainstates = chainman.
GetAll();
590 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
593 this->LoadVerifyActivateChainstate();
596 LOCK(chainman_restarted.GetMutex());
598 BOOST_CHECK(chainman_restarted.IsSnapshotActive());
599 BOOST_CHECK(!chainman_restarted.IsSnapshotValidated());
601 BOOST_CHECK_EQUAL(chainman_restarted.ActiveTip()->GetBlockHash(), snapshot_tip_hash);
606 "Ensure we can mine blocks on top of the initialized snapshot chainstate");
609 LOCK(chainman_restarted.GetMutex());
615 if (
cs != &chainman_restarted.ActiveChainstate()) {
624 this->SetupSnapshot();
642 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
653 auto all_chainstates = chainman.
GetAll();
658 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
672 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
676 this->LoadVerifyActivateChainstate();
697 "Ensure we can mine blocks on top of the \"new\" IBD chainstate");
707 auto chainstates = this->SetupSnapshot();
708 Chainstate& validation_chainstate = *std::get<0>(chainstates);
716 return validation_chainstate.
CoinsTip());
729 res =
WITH_LOCK(::
cs_main,
return chainman.MaybeCompleteSnapshotValidation());
733 auto all_chainstates = chainman.GetAll();
746 BOOST_TEST_MESSAGE(
"Performing Load/Verify/Activate of chainstate");
750 this->LoadVerifyActivateChainstate();
764 "Ensure we can mine blocks on top of the \"new\" IBD chainstate");
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...
std::unique_ptr< node::Warnings > warnings
Manages all the node warnings.
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...
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()
std::atomic< int > exit_status
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
util::SignalInterrupt * shutdown
Interrupt object used to track whether node shutdown was requested.
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...
std::optional< fs::path > FindSnapshotChainstateDir(const fs::path &data_dir)
Return a path to the snapshot-based chainstate dir, if one exists.
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.
Non-refcounted RAII wrapper for FILE*.
void SetTip(CBlockIndex &block)
Set/initialize a chain with a given tip.
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_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 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)
static uint256 InsecureRand256()
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)
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.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
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.
static uint32_t InsecureRand32()
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())
static uint64_t InsecureRandBits(int bits)
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
std::optional< uint256 > SnapshotBlockhash() const
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
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...
bilingual_str _(ConstevalStringLiteral str)
Translation function.
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)
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.