1 // Copyright (c) 2014-2015 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.
7 #include "test/test_bitcoin.h"
8 #include "test/test_random.h"
12 #include <boost/test/unit_test.hpp>
14 #define SKIPLIST_LENGTH 300000
16 BOOST_FIXTURE_TEST_SUITE(skiplist_tests
, BasicTestingSetup
)
18 BOOST_AUTO_TEST_CASE(skiplist_test
)
20 std::vector
<CBlockIndex
> vIndex(SKIPLIST_LENGTH
);
22 for (int i
=0; i
<SKIPLIST_LENGTH
; i
++) {
23 vIndex
[i
].nHeight
= i
;
24 vIndex
[i
].pprev
= (i
== 0) ? NULL
: &vIndex
[i
- 1];
25 vIndex
[i
].BuildSkip();
28 for (int i
=0; i
<SKIPLIST_LENGTH
; i
++) {
30 BOOST_CHECK(vIndex
[i
].pskip
== &vIndex
[vIndex
[i
].pskip
->nHeight
]);
31 BOOST_CHECK(vIndex
[i
].pskip
->nHeight
< i
);
33 BOOST_CHECK(vIndex
[i
].pskip
== NULL
);
37 for (int i
=0; i
< 1000; i
++) {
38 int from
= insecure_rand() % (SKIPLIST_LENGTH
- 1);
39 int to
= insecure_rand() % (from
+ 1);
41 BOOST_CHECK(vIndex
[SKIPLIST_LENGTH
- 1].GetAncestor(from
) == &vIndex
[from
]);
42 BOOST_CHECK(vIndex
[from
].GetAncestor(to
) == &vIndex
[to
]);
43 BOOST_CHECK(vIndex
[from
].GetAncestor(0) == &vIndex
[0]);
47 BOOST_AUTO_TEST_CASE(getlocator_test
)
49 // Build a main chain 100000 blocks long.
50 std::vector
<uint256
> vHashMain(100000);
51 std::vector
<CBlockIndex
> vBlocksMain(100000);
52 for (unsigned int i
=0; i
<vBlocksMain
.size(); i
++) {
53 vHashMain
[i
] = ArithToUint256(i
); // Set the hash equal to the height, so we can quickly check the distances.
54 vBlocksMain
[i
].nHeight
= i
;
55 vBlocksMain
[i
].pprev
= i
? &vBlocksMain
[i
- 1] : NULL
;
56 vBlocksMain
[i
].phashBlock
= &vHashMain
[i
];
57 vBlocksMain
[i
].BuildSkip();
58 BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain
[i
].GetBlockHash()).GetLow64(), vBlocksMain
[i
].nHeight
);
59 BOOST_CHECK(vBlocksMain
[i
].pprev
== NULL
|| vBlocksMain
[i
].nHeight
== vBlocksMain
[i
].pprev
->nHeight
+ 1);
62 // Build a branch that splits off at block 49999, 50000 blocks long.
63 std::vector
<uint256
> vHashSide(50000);
64 std::vector
<CBlockIndex
> vBlocksSide(50000);
65 for (unsigned int i
=0; i
<vBlocksSide
.size(); i
++) {
66 vHashSide
[i
] = ArithToUint256(i
+ 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
67 vBlocksSide
[i
].nHeight
= i
+ 50000;
68 vBlocksSide
[i
].pprev
= i
? &vBlocksSide
[i
- 1] : &vBlocksMain
[49999];
69 vBlocksSide
[i
].phashBlock
= &vHashSide
[i
];
70 vBlocksSide
[i
].BuildSkip();
71 BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide
[i
].GetBlockHash()).GetLow64(), vBlocksSide
[i
].nHeight
);
72 BOOST_CHECK(vBlocksSide
[i
].pprev
== NULL
|| vBlocksSide
[i
].nHeight
== vBlocksSide
[i
].pprev
->nHeight
+ 1);
75 // Build a CChain for the main branch.
77 chain
.SetTip(&vBlocksMain
.back());
79 // Test 100 random starting points for locators.
80 for (int n
=0; n
<100; n
++) {
81 int r
= insecure_rand() % 150000;
82 CBlockIndex
* tip
= (r
< 100000) ? &vBlocksMain
[r
] : &vBlocksSide
[r
- 100000];
83 CBlockLocator locator
= chain
.GetLocator(tip
);
85 // The first result must be the block itself, the last one must be genesis.
86 BOOST_CHECK(locator
.vHave
.front() == tip
->GetBlockHash());
87 BOOST_CHECK(locator
.vHave
.back() == vBlocksMain
[0].GetBlockHash());
89 // Entries 1 through 11 (inclusive) go back one step each.
90 for (unsigned int i
= 1; i
< 12 && i
< locator
.vHave
.size() - 1; i
++) {
91 BOOST_CHECK_EQUAL(UintToArith256(locator
.vHave
[i
]).GetLow64(), tip
->nHeight
- i
);
94 // The further ones (excluding the last one) go back with exponential steps.
95 unsigned int dist
= 2;
96 for (unsigned int i
= 12; i
< locator
.vHave
.size() - 1; i
++) {
97 BOOST_CHECK_EQUAL(UintToArith256(locator
.vHave
[i
- 1]).GetLow64() - UintToArith256(locator
.vHave
[i
]).GetLow64(), dist
);
103 BOOST_AUTO_TEST_SUITE_END()