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