-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathtxindex_tests.cpp
More file actions
102 lines (83 loc) · 3.99 KB
/
txindex_tests.cpp
File metadata and controls
102 lines (83 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) 2017-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
#include <index/txindex.h>
#include <script/standard.h>
#include <test/util/setup_common.h>
#include <util/time.h>
#include <validation.h>
#include <validationinterface.h>
#include <wallet/wallet.h>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(txindex_tests)
BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
{
TxIndex txindex(1 << 20, true);
CTransactionRef tx_disk;
uint256 block_hash;
// Transaction should not be found in the index before it is started.
for (const auto& txn : m_coinbase_txns) {
BOOST_CHECK(!txindex.FindTx(txn->GetHash(), block_hash, tx_disk));
}
// BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(txindex.Start(m_node.chainman->ActiveChainstate()));
// Allow tx index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000;
int64_t time_start = GetTimeMillis();
while (!txindex.BlockUntilSyncedToCurrentChain()) {
BOOST_REQUIRE(time_start + timeout_ms > GetTimeMillis());
UninterruptibleSleep(std::chrono::milliseconds{100});
}
// Check that txindex excludes genesis block transactions.
const CBlock& genesis_block = Params().GenesisBlock();
for (const auto& txn : genesis_block.vtx) {
BOOST_CHECK(!txindex.FindTx(txn->GetHash(), block_hash, tx_disk));
}
// Check that txindex has all txs that were in the chain before it started.
for (const auto& txn : m_coinbase_txns) {
if (!txindex.FindTx(txn->GetHash(), block_hash, tx_disk)) {
BOOST_ERROR("FindTx failed");
} else if (tx_disk->GetHash() != txn->GetHash()) {
BOOST_ERROR("Read incorrect tx");
}
}
// Check that new transactions in new blocks make it into the index.
// Note: TestChain100Setup creates blocks up to height 100, with PoW ending at block 89
// So we must use PoS blocks for additional blocks
for (int i = 0; i < 10; i++) {
CScript coinbase_script_pub_key = GetScriptForDestination(PKHash(coinbaseKey.GetPubKey()));
std::vector<CMutableTransaction> no_txns;
const CBlock& block = CreateAndProcessPoSBlock(no_txns, coinbase_script_pub_key, m_wallet.get());
// CRITICAL: Ensure wallet receives and processes block notifications before creating next block
// 1. Sync validation interface queue to process all pending notifications
SyncWithValidationInterfaceQueue();
// 2. Wait for wallet to sync to the current chain tip
m_wallet->BlockUntilSyncedToCurrentChain();
// 3. Force wallet to re-evaluate all transactions and update spent status
{
LOCK(m_wallet->cs_wallet);
m_wallet->ReacceptWalletTransactions();
}
// 4. Extra sync to ensure wallet has fully processed the coinstake transaction
SyncWithValidationInterfaceQueue();
m_wallet->BlockUntilSyncedToCurrentChain();
// PoS blocks have coinstake as vtx[1]
BOOST_REQUIRE(block.vtx.size() >= 2);
const CTransaction& txn = *block.vtx[1];
BOOST_CHECK(txindex.BlockUntilSyncedToCurrentChain());
if (!txindex.FindTx(txn.GetHash(), block_hash, tx_disk)) {
BOOST_ERROR("FindTx failed");
} else if (tx_disk->GetHash() != txn.GetHash()) {
BOOST_ERROR("Read incorrect tx");
}
// Increment mock time by 60 seconds to allow coins to gain stake age for next block
SetMockTime(GetTime() + 60);
}
// shutdown sequence (c.f. Shutdown() in init.cpp)
txindex.Stop();
// Let scheduler events finish running to avoid accessing any memory related to txindex after it is destructed
SyncWithValidationInterfaceQueue();
}
BOOST_AUTO_TEST_SUITE_END()