Branch data Line data Source code
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>
6 : : #include <consensus/validation.h>
7 : : #include <interfaces/chain.h>
8 : : #include <test/util/setup_common.h>
9 : : #include <script/solver.h>
10 : : #include <validation.h>
11 : :
12 : : #include <boost/test/unit_test.hpp>
13 : :
14 : : using interfaces::FoundBlock;
15 : :
16 : 0 : BOOST_FIXTURE_TEST_SUITE(interfaces_tests, TestChain100Setup)
17 : 0 :
18 : 0 : BOOST_AUTO_TEST_CASE(findBlock)
19 : : {
20 : 0 : LOCK(Assert(m_node.chainman)->GetMutex());
21 : 0 : auto& chain = m_node.chain;
22 : 0 : const CChain& active = Assert(m_node.chainman)->ActiveChain();
23 : :
24 : 0 : uint256 hash;
25 : 0 : BOOST_CHECK(chain->findBlock(active[10]->GetBlockHash(), FoundBlock().hash(hash)));
26 : 0 : BOOST_CHECK_EQUAL(hash, active[10]->GetBlockHash());
27 : :
28 : 0 : int height = -1;
29 : 0 : BOOST_CHECK(chain->findBlock(active[20]->GetBlockHash(), FoundBlock().height(height)));
30 : 0 : BOOST_CHECK_EQUAL(height, active[20]->nHeight);
31 : :
32 : 0 : CBlock data;
33 : 0 : BOOST_CHECK(chain->findBlock(active[30]->GetBlockHash(), FoundBlock().data(data)));
34 : 0 : BOOST_CHECK_EQUAL(data.GetHash(), active[30]->GetBlockHash());
35 : :
36 : 0 : int64_t time = -1;
37 : 0 : BOOST_CHECK(chain->findBlock(active[40]->GetBlockHash(), FoundBlock().time(time)));
38 : 0 : BOOST_CHECK_EQUAL(time, active[40]->GetBlockTime());
39 : :
40 : 0 : int64_t max_time = -1;
41 : 0 : BOOST_CHECK(chain->findBlock(active[50]->GetBlockHash(), FoundBlock().maxTime(max_time)));
42 : 0 : BOOST_CHECK_EQUAL(max_time, active[50]->GetBlockTimeMax());
43 : :
44 : 0 : int64_t mtp_time = -1;
45 : 0 : BOOST_CHECK(chain->findBlock(active[60]->GetBlockHash(), FoundBlock().mtpTime(mtp_time)));
46 : 0 : BOOST_CHECK_EQUAL(mtp_time, active[60]->GetMedianTimePast());
47 : :
48 : 0 : bool cur_active{false}, next_active{false};
49 : 0 : uint256 next_hash;
50 : 0 : BOOST_CHECK_EQUAL(active.Height(), 100);
51 : 0 : BOOST_CHECK(chain->findBlock(active[99]->GetBlockHash(), FoundBlock().inActiveChain(cur_active).nextBlock(FoundBlock().inActiveChain(next_active).hash(next_hash))));
52 : 0 : BOOST_CHECK(cur_active);
53 : 0 : BOOST_CHECK(next_active);
54 : 0 : BOOST_CHECK_EQUAL(next_hash, active[100]->GetBlockHash());
55 : 0 : cur_active = next_active = false;
56 : 0 : BOOST_CHECK(chain->findBlock(active[100]->GetBlockHash(), FoundBlock().inActiveChain(cur_active).nextBlock(FoundBlock().inActiveChain(next_active))));
57 : 0 : BOOST_CHECK(cur_active);
58 : 0 : BOOST_CHECK(!next_active);
59 : :
60 : 0 : BOOST_CHECK(!chain->findBlock({}, FoundBlock()));
61 : 0 : }
62 : :
63 : 0 : BOOST_AUTO_TEST_CASE(findFirstBlockWithTimeAndHeight)
64 : : {
65 : 0 : LOCK(Assert(m_node.chainman)->GetMutex());
66 : 0 : auto& chain = m_node.chain;
67 : 0 : const CChain& active = Assert(m_node.chainman)->ActiveChain();
68 : 0 : uint256 hash;
69 : : int height;
70 : 0 : BOOST_CHECK(chain->findFirstBlockWithTimeAndHeight(/* min_time= */ 0, /* min_height= */ 5, FoundBlock().hash(hash).height(height)));
71 : 0 : BOOST_CHECK_EQUAL(hash, active[5]->GetBlockHash());
72 : 0 : BOOST_CHECK_EQUAL(height, 5);
73 : 0 : BOOST_CHECK(!chain->findFirstBlockWithTimeAndHeight(/* min_time= */ active.Tip()->GetBlockTimeMax() + 1, /* min_height= */ 0));
74 : 0 : }
75 : :
76 : 0 : BOOST_AUTO_TEST_CASE(findAncestorByHeight)
77 : : {
78 : 0 : LOCK(Assert(m_node.chainman)->GetMutex());
79 : 0 : auto& chain = m_node.chain;
80 : 0 : const CChain& active = Assert(m_node.chainman)->ActiveChain();
81 : 0 : uint256 hash;
82 : 0 : BOOST_CHECK(chain->findAncestorByHeight(active[20]->GetBlockHash(), 10, FoundBlock().hash(hash)));
83 : 0 : BOOST_CHECK_EQUAL(hash, active[10]->GetBlockHash());
84 : 0 : BOOST_CHECK(!chain->findAncestorByHeight(active[10]->GetBlockHash(), 20));
85 : 0 : }
86 : :
87 : 0 : BOOST_AUTO_TEST_CASE(findAncestorByHash)
88 : : {
89 : 0 : LOCK(Assert(m_node.chainman)->GetMutex());
90 : 0 : auto& chain = m_node.chain;
91 : 0 : const CChain& active = Assert(m_node.chainman)->ActiveChain();
92 : 0 : int height = -1;
93 : 0 : BOOST_CHECK(chain->findAncestorByHash(active[20]->GetBlockHash(), active[10]->GetBlockHash(), FoundBlock().height(height)));
94 : 0 : BOOST_CHECK_EQUAL(height, 10);
95 : 0 : BOOST_CHECK(!chain->findAncestorByHash(active[10]->GetBlockHash(), active[20]->GetBlockHash()));
96 : 0 : }
97 : :
98 : 0 : BOOST_AUTO_TEST_CASE(findCommonAncestor)
99 : : {
100 : 0 : auto& chain = m_node.chain;
101 : 0 : const CChain& active{*WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return &Assert(m_node.chainman)->ActiveChain())};
102 : 0 : auto* orig_tip = active.Tip();
103 : 0 : for (int i = 0; i < 10; ++i) {
104 : 0 : BlockValidationState state;
105 : 0 : m_node.chainman->ActiveChainstate().InvalidateBlock(state, active.Tip());
106 : 0 : }
107 : 0 : BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10);
108 : 0 : coinbaseKey.MakeNewKey(true);
109 : 0 : for (int i = 0; i < 20; ++i) {
110 : 0 : CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
111 : 0 : }
112 : 0 : BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight + 10);
113 : 0 : uint256 fork_hash;
114 : : int fork_height;
115 : : int orig_height;
116 : 0 : BOOST_CHECK(chain->findCommonAncestor(orig_tip->GetBlockHash(), active.Tip()->GetBlockHash(), FoundBlock().height(fork_height).hash(fork_hash), FoundBlock().height(orig_height)));
117 : 0 : BOOST_CHECK_EQUAL(orig_height, orig_tip->nHeight);
118 : 0 : BOOST_CHECK_EQUAL(fork_height, orig_tip->nHeight - 10);
119 : 0 : BOOST_CHECK_EQUAL(fork_hash, active[fork_height]->GetBlockHash());
120 : :
121 : 0 : uint256 active_hash, orig_hash;
122 : 0 : BOOST_CHECK(!chain->findCommonAncestor(active.Tip()->GetBlockHash(), {}, {}, FoundBlock().hash(active_hash), {}));
123 : 0 : BOOST_CHECK(!chain->findCommonAncestor({}, orig_tip->GetBlockHash(), {}, {}, FoundBlock().hash(orig_hash)));
124 : 0 : BOOST_CHECK_EQUAL(active_hash, active.Tip()->GetBlockHash());
125 : 0 : BOOST_CHECK_EQUAL(orig_hash, orig_tip->GetBlockHash());
126 : 0 : }
127 : :
128 : 0 : BOOST_AUTO_TEST_CASE(hasBlocks)
129 : : {
130 : 0 : LOCK(::cs_main);
131 : 0 : auto& chain = m_node.chain;
132 : 0 : const CChain& active = Assert(m_node.chainman)->ActiveChain();
133 : :
134 : : // Test ranges
135 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 10, 90));
136 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 10, {}));
137 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 0, 90));
138 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 0, {}));
139 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), -1000, 1000));
140 : 0 : active[5]->nStatus &= ~BLOCK_HAVE_DATA;
141 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 10, 90));
142 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 10, {}));
143 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, 90));
144 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, {}));
145 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), -1000, 1000));
146 : 0 : active[95]->nStatus &= ~BLOCK_HAVE_DATA;
147 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 10, 90));
148 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 10, {}));
149 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, 90));
150 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, {}));
151 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), -1000, 1000));
152 : 0 : active[50]->nStatus &= ~BLOCK_HAVE_DATA;
153 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 10, 90));
154 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 10, {}));
155 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, 90));
156 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 0, {}));
157 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), -1000, 1000));
158 : :
159 : : // Test edge cases
160 : 0 : BOOST_CHECK(chain->hasBlocks(active.Tip()->GetBlockHash(), 6, 49));
161 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 5, 49));
162 : 0 : BOOST_CHECK(!chain->hasBlocks(active.Tip()->GetBlockHash(), 6, 50));
163 : 0 : }
164 : :
165 : 0 : BOOST_AUTO_TEST_SUITE_END()
|