]>
Commit | Line | Data |
---|---|---|
e8b5f0d5 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | // Copyright (c) 2009-2014 The Bitcoin developers | |
3 | // Distributed under the MIT/X11 software license, see the accompanying | |
4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | |
5 | ||
6 | #include "chain.h" | |
7 | ||
8 | using namespace std; | |
9 | ||
10 | // CChain implementation | |
11 | ||
12 | CBlockIndex *CChain::SetTip(CBlockIndex *pindex) { | |
13 | if (pindex == NULL) { | |
14 | vChain.clear(); | |
15 | return NULL; | |
16 | } | |
17 | vChain.resize(pindex->nHeight + 1); | |
18 | while (pindex && vChain[pindex->nHeight] != pindex) { | |
19 | vChain[pindex->nHeight] = pindex; | |
20 | pindex = pindex->pprev; | |
21 | } | |
22 | return pindex; | |
23 | } | |
24 | ||
25 | CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { | |
26 | int nStep = 1; | |
27 | std::vector<uint256> vHave; | |
28 | vHave.reserve(32); | |
29 | ||
30 | if (!pindex) | |
31 | pindex = Tip(); | |
32 | while (pindex) { | |
33 | vHave.push_back(pindex->GetBlockHash()); | |
34 | // Stop when we have added the genesis block. | |
35 | if (pindex->nHeight == 0) | |
36 | break; | |
37 | // Exponentially larger steps back, plus the genesis block. | |
38 | int nHeight = std::max(pindex->nHeight - nStep, 0); | |
39 | if (Contains(pindex)) { | |
40 | // Use O(1) CChain index if possible. | |
41 | pindex = (*this)[nHeight]; | |
42 | } else { | |
43 | // Otherwise, use O(log n) skiplist. | |
44 | pindex = pindex->GetAncestor(nHeight); | |
45 | } | |
46 | if (vHave.size() > 10) | |
47 | nStep *= 2; | |
48 | } | |
49 | ||
50 | return CBlockLocator(vHave); | |
51 | } | |
52 | ||
53 | const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { | |
54 | if (pindex->nHeight > Height()) | |
55 | pindex = pindex->GetAncestor(Height()); | |
56 | while (pindex && !Contains(pindex)) | |
57 | pindex = pindex->pprev; | |
58 | return pindex; | |
59 | } |