Skip to content

Commit 673a5bd

Browse files
committed
test: validation: add unittest for UpdateTip behavior
1 parent 2705570 commit 673a5bd

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/test/validation_chainstate_tests.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
//
5+
#include <chainparams.h>
56
#include <random.h>
67
#include <uint256.h>
78
#include <consensus/validation.h>
89
#include <sync.h>
10+
#include <rpc/blockchain.h>
11+
#include <test/util/chainstate.h>
912
#include <test/util/setup_common.h>
1013
#include <validation.h>
1114

@@ -72,4 +75,77 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
7275
WITH_LOCK(::cs_main, manager.Unload());
7376
}
7477

78+
//! Test UpdateTip behavior for both active and background chainstates.
79+
//!
80+
//! When run on the background chainstate, UpdateTip should do a subset
81+
//! of what it does for the active chainstate.
82+
BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
83+
{
84+
ChainstateManager& chainman = *Assert(m_node.chainman);
85+
uint256 curr_tip = ::g_best_block;
86+
87+
// Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
88+
// be found.
89+
mineBlocks(10);
90+
91+
// After adding some blocks to the tip, best block should have changed.
92+
BOOST_CHECK(::g_best_block != curr_tip);
93+
94+
BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root));
95+
96+
// Ensure our active chain is the snapshot chainstate.
97+
BOOST_CHECK(chainman.IsSnapshotActive());
98+
99+
curr_tip = ::g_best_block;
100+
101+
// Mine a new block on top of the activated snapshot chainstate.
102+
mineBlocks(1); // Defined in TestChain100Setup.
103+
104+
// After adding some blocks to the snapshot tip, best block should have changed.
105+
BOOST_CHECK(::g_best_block != curr_tip);
106+
107+
curr_tip = ::g_best_block;
108+
109+
CChainState* background_cs;
110+
111+
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 2);
112+
for (CChainState* cs : chainman.GetAll()) {
113+
if (cs != &chainman.ActiveChainstate()) {
114+
background_cs = cs;
115+
}
116+
}
117+
BOOST_CHECK(background_cs);
118+
119+
// Create a block to append to the validation chain.
120+
std::vector<CMutableTransaction> noTxns;
121+
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
122+
CBlock validation_block = this->CreateBlock(noTxns, scriptPubKey, *background_cs);
123+
auto pblock = std::make_shared<const CBlock>(validation_block);
124+
BlockValidationState state;
125+
CBlockIndex* pindex = nullptr;
126+
const CChainParams& chainparams = Params();
127+
bool newblock = false;
128+
129+
// TODO: much of this is inlined from ProcessNewBlock(); just reuse PNB()
130+
// once it is changed to support multiple chainstates.
131+
{
132+
LOCK(::cs_main);
133+
bool checked = CheckBlock(*pblock, state, chainparams.GetConsensus());
134+
BOOST_CHECK(checked);
135+
bool accepted = background_cs->AcceptBlock(
136+
pblock, state, &pindex, true, nullptr, &newblock);
137+
BOOST_CHECK(accepted);
138+
}
139+
// UpdateTip is called here
140+
bool block_added = background_cs->ActivateBestChain(state, pblock);
141+
142+
// Ensure tip is as expected
143+
BOOST_CHECK_EQUAL(background_cs->m_chain.Tip()->GetBlockHash(), validation_block.GetHash());
144+
145+
// g_best_block should be unchanged after adding a block to the background
146+
// validation chain.
147+
BOOST_CHECK(block_added);
148+
BOOST_CHECK_EQUAL(curr_tip, ::g_best_block);
149+
}
150+
75151
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)