Bitcoin Core 22.99.0
P2P Digital Currency
validation_chainstate_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2020 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>
6#include <random.h>
7#include <uint256.h>
9#include <sync.h>
10#include <rpc/blockchain.h>
13#include <validation.h>
14
15#include <vector>
16
17#include <boost/test/unit_test.hpp>
18
19BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, TestingSetup)
20
21
23BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
24{
25 ChainstateManager manager;
26 WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
27 CTxMemPool mempool;
28
30 auto add_coin = [](CCoinsViewCache& coins_view) -> COutPoint {
31 Coin newcoin;
32 uint256 txid = InsecureRand256();
33 COutPoint outp{txid, 0};
34 newcoin.nHeight = 1;
35 newcoin.out.nValue = InsecureRand32();
36 newcoin.out.scriptPubKey.assign((uint32_t)56, 1);
37 coins_view.AddCoin(outp, std::move(newcoin), false);
38
39 return outp;
40 };
41
42 CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool));
43 c1.InitCoinsDB(
44 /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
45 WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
46
47 // Add a coin to the in-memory cache, upsize once, then downsize.
48 {
49 LOCK(::cs_main);
50 auto outpoint = add_coin(c1.CoinsTip());
51
52 // Set a meaningless bestblock value in the coinsview cache - otherwise we won't
53 // flush during ResizecoinsCaches() and will subsequently hit an assertion.
55
56 BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
57
58 c1.ResizeCoinsCaches(
59 1 << 24, // upsizing the coinsview cache
60 1 << 22 // downsizing the coinsdb cache
61 );
62
63 // View should still have the coin cached, since we haven't destructed the cache on upsize.
64 BOOST_CHECK(c1.CoinsTip().HaveCoinInCache(outpoint));
65
66 c1.ResizeCoinsCaches(
67 1 << 22, // downsizing the coinsview cache
68 1 << 23 // upsizing the coinsdb cache
69 );
70
71 // The view cache should be empty since we had to destruct to downsize.
72 BOOST_CHECK(!c1.CoinsTip().HaveCoinInCache(outpoint));
73 }
74
75 // Avoid triggering the address sanitizer.
76 WITH_LOCK(::cs_main, manager.Unload());
77}
78
84{
86 uint256 curr_tip = ::g_best_block;
87
88 // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
89 // be found.
90 mineBlocks(10);
91
92 // After adding some blocks to the tip, best block should have changed.
93 BOOST_CHECK(::g_best_block != curr_tip);
94
95 BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root));
96
97 // Ensure our active chain is the snapshot chainstate.
98 BOOST_CHECK(chainman.IsSnapshotActive());
99
100 curr_tip = ::g_best_block;
101
102 // Mine a new block on top of the activated snapshot chainstate.
103 mineBlocks(1); // Defined in TestChain100Setup.
104
105 // After adding some blocks to the snapshot tip, best block should have changed.
106 BOOST_CHECK(::g_best_block != curr_tip);
107
108 curr_tip = ::g_best_block;
109
110 BOOST_CHECK_EQUAL(chainman.GetAll().size(), 2);
111
112 CChainState& background_cs{*[&] {
113 for (CChainState* cs : chainman.GetAll()) {
114 if (cs != &chainman.ActiveChainstate()) {
115 return cs;
116 }
117 }
118 assert(false);
119 }()};
120
121 // Create a block to append to the validation chain.
122 std::vector<CMutableTransaction> noTxns;
123 CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
124 CBlock validation_block = this->CreateBlock(noTxns, scriptPubKey, background_cs);
125 auto pblock = std::make_shared<const CBlock>(validation_block);
127 CBlockIndex* pindex = nullptr;
128 const CChainParams& chainparams = Params();
129 bool newblock = false;
130
131 // TODO: much of this is inlined from ProcessNewBlock(); just reuse PNB()
132 // once it is changed to support multiple chainstates.
133 {
134 LOCK(::cs_main);
135 bool checked = CheckBlock(*pblock, state, chainparams.GetConsensus());
136 BOOST_CHECK(checked);
137 bool accepted = background_cs.AcceptBlock(
138 pblock, state, &pindex, true, nullptr, &newblock);
139 BOOST_CHECK(accepted);
140 }
141 // UpdateTip is called here
142 bool block_added = background_cs.ActivateBestChain(state, pblock);
143
144 // Ensure tip is as expected
145 BOOST_CHECK_EQUAL(background_cs.m_chain.Tip()->GetBlockHash(), validation_block.GetHash());
146
147 // g_best_block should be unchanged after adding a block to the background
148 // validation chain.
149 BOOST_CHECK(block_added);
150 BOOST_CHECK_EQUAL(curr_tip, ::g_best_block);
151}
152
NodeContext m_node
Definition: bitcoin-gui.cpp:36
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: validation.cpp:118
const CChainParams & Params()
Return the currently selected parameters.
static bool CreateAndActivateUTXOSnapshot(NodeContext &node, const fs::path root, F malleation=NoMalleation)
Create and activate a UTXO snapshot, optionally providing a function to malleate the snapshot.
Definition: chainstate.h:27
#define Assert(val)
Identity function.
Definition: check.h:57
uint256 GetHash() const
Definition: block.cpp:11
Definition: block.h:63
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:146
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:70
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:82
CChainState stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:544
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:638
void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, std::string leveldb_name="chainstate")
Initialize the CoinsViews UTXO set database management data structures.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:214
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:162
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:151
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:27
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:424
CScript scriptPubKey
Definition: transaction.h:132
CAmount nValue
Definition: transaction.h:131
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:847
CChainState &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
Definition: validation.h:925
CChainState & ActiveChainstate() const
The most-work chain.
bool IsSnapshotActive() const
A UTXO entry.
Definition: coins.h:31
CTxOut out
unspent transaction output
Definition: coins.h:34
uint32_t nHeight
at which height this containing transaction was included in the active block chain
Definition: coins.h:40
void assign(size_type n, const T &val)
Definition: prevector.h:218
256-bit opaque blob.
Definition: uint256.h:124
static void add_coin(const CAmount &nValue, int nInput, std::vector< OutputGroup > &set)
BOOST_AUTO_TEST_SUITE_END()
static void pool cs
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
@ OP_CHECKSIG
Definition: script.h:183
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:60
static uint256 InsecureRand256()
Definition: setup_common.h:66
static uint32_t InsecureRand32()
Definition: setup_common.h:65
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:47
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:116
Testing setup that configures a complete environment.
Definition: setup_common.h:99
#define LOCK(cs)
Definition: sync.h:226
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:270
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.
Definition: validation.cpp:123
assert(!tx.IsCoinBase())
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 CChainState caches during runtime.