Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
validation_chainstate_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2020-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4//
5#include <chainparams.h>
7#include <random.h>
8#include <rpc/blockchain.h>
9#include <sync.h>
11#include <test/util/coins.h>
12#include <test/util/random.h>
14#include <uint256.h>
15#include <util/check.h>
16#include <validation.h>
17
18#include <vector>
19
20#include <boost/test/unit_test.hpp>
21
22BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, ChainTestingSetup)
23
24
26BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
27{
29 CTxMemPool& mempool = *Assert(m_node.mempool);
30 Chainstate& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool));
31 c1.InitCoinsDB(
32 /*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
33 WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
34 BOOST_REQUIRE(c1.LoadGenesisBlock()); // Need at least one block loaded to be able to flush caches
35
36 // Add a coin to the in-memory cache, upsize once, then downsize.
37 {
39 const auto outpoint = AddTestCoin(c1.CoinsTip());
40
41 // Set a meaningless bestblock value in the coinsview cache - otherwise we won't
42 // flush during ResizecoinsCaches() and will subsequently hit an assertion.
44
45 BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
46
47 c1.ResizeCoinsCaches(
48 1 << 24, // upsizing the coinsview cache
49 1 << 22 // downsizing the coinsdb cache
50 );
51
52 // View should still have the coin cached, since we haven't destructed the cache on upsize.
53 BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
54
55 c1.ResizeCoinsCaches(
56 1 << 22, // downsizing the coinsview cache
57 1 << 23 // upsizing the coinsdb cache
58 );
59
60 // The view cache should be empty since we had to destruct to downsize.
61 BOOST_CHECK(!c1.CoinsTip().HaveCoinInCache(outpoint));
62 }
63}
64
70{
72 uint256 curr_tip = ::g_best_block;
73
74 // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
75 // be found.
76 mineBlocks(10);
77
78 // After adding some blocks to the tip, best block should have changed.
79 BOOST_CHECK(::g_best_block != curr_tip);
80
81 // Grab block 1 from disk; we'll add it to the background chain later.
82 std::shared_ptr<CBlock> pblockone = std::make_shared<CBlock>();
83 {
85 chainman.m_blockman.ReadBlockFromDisk(*pblockone, *chainman.ActiveChain()[1]);
86 }
87
89 this, NoMalleation, /*reset_chainstate=*/ true));
90
91 // Ensure our active chain is the snapshot chainstate.
93
94 curr_tip = ::g_best_block;
95
96 // Mine a new block on top of the activated snapshot chainstate.
97 mineBlocks(1); // Defined in TestChain100Setup.
98
99 // After adding some blocks to the snapshot tip, best block should have changed.
100 BOOST_CHECK(::g_best_block != curr_tip);
101
102 curr_tip = ::g_best_block;
103
104 BOOST_CHECK_EQUAL(chainman.GetAll().size(), 2);
105
106 Chainstate& background_cs{*Assert([&]() -> Chainstate* {
107 for (Chainstate* cs : chainman.GetAll()) {
108 if (cs != &chainman.ActiveChainstate()) {
109 return cs;
110 }
111 }
112 return nullptr;
113 }())};
114
115 // Append the first block to the background chain.
117 CBlockIndex* pindex = nullptr;
118 const CChainParams& chainparams = Params();
119 bool newblock = false;
120
121 // TODO: much of this is inlined from ProcessNewBlock(); just reuse PNB()
122 // once it is changed to support multiple chainstates.
123 {
125 bool checked = CheckBlock(*pblockone, state, chainparams.GetConsensus());
126 BOOST_CHECK(checked);
127 bool accepted = chainman.AcceptBlock(
128 pblockone, state, &pindex, true, nullptr, &newblock, true);
129 BOOST_CHECK(accepted);
130 }
131
132 // UpdateTip is called here
133 bool block_added = background_cs.ActivateBestChain(state, pblockone);
134
135 // Ensure tip is as expected
136 BOOST_CHECK_EQUAL(background_cs.m_chain.Tip()->GetBlockHash(), pblockone->GetHash());
137
138 // g_best_block should be unchanged after adding a block to the background
139 // validation chain.
140 BOOST_CHECK(block_added);
142}
143
node::NodeContext m_node
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
Definition check.h:77
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition chain.h:141
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition chainparams.h:81
const Consensus::Params & GetConsensus() const
Definition chainparams.h:93
void SetBestBlock(const uint256 &hashBlock)
Definition coins.cpp:181
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition coins.cpp:170
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:304
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition validation.h:513
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Definition validation.h:619
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
ChainstateRole GetRole() const EXCLUSIVE_LOCKS_REQUIRED(void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, fs::path leveldb_name="chainstate")
Return the current role of the chainstate.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition validation.h:871
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...
bool IsSnapshotActive() const
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Chainstate &InitializeChainstate(CTxMemPool *mempool) EXCLUSIVE_LOCKS_REQUIRED(std::vector< Chainstate * GetAll)()
Instantiate a new chainstate.
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, BlockValidationState &state, CBlockIndex **ppindex, bool fRequested, const FlatFilePos *dbp, bool *fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Sufficiently validate a block for disk storage (and store on disk).
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos) const
Functions for disk access for blocks.
256-bit opaque blob.
Definition uint256.h:178
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:8
BOOST_AUTO_TEST_SUITE_END()
static void pool cs
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:18
#define BOOST_CHECK(expr)
Definition object.cpp:17
Testing setup that performs all steps up until right before ChainstateManager gets initialized.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
std::unique_ptr< CTxMemPool > mempool
Definition context.h:65
std::unique_ptr< ChainstateManager > chainman
Definition context.h:69
#define LOCK(cs)
Definition sync.h:257
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition sync.h:301
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.
Definition chainstate.h:33
const auto NoMalleation
Definition chainstate.h:19
COutPoint AddTestCoin(CCoinsViewCache &coins_view)
Create a Coin with DynamicMemoryUsage of 80 bytes and add it to the given view.
Definition coins.cpp:16
static uint256 InsecureRand256()
Definition random.h:35
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
uint256 g_best_block
Used to notify getblocktemplate RPC of new tips.
BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
Test UpdateTip behavior for both active and background chainstates.
BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
Test resizing coins-related Chainstate caches during runtime.