mirror of https://github.com/bitcoin/bitcoin.git
chain: make use of pskip in LastCommonAncestor (optimization)
By using the pskip pointer, which regularly allows jumping back much faster than pprev, the forking point between two CBlockIndex entries can be found much faster. A simulation shows that no more than 136 steps are needed to jump anywhere within the first 2^20 block heights, and on average 65 jumps for uniform forking points around that height.
This commit is contained in:
parent
2e09d66fbb
commit
3635d62f5a
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <chain.h>
|
||||
#include <tinyformat.h>
|
||||
#include <util/check.h>
|
||||
#include <util/time.h>
|
||||
|
||||
std::string CBlockFileInfo::ToString() const
|
||||
|
@ -158,18 +159,26 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr
|
|||
/** Find the last common ancestor two blocks have.
|
||||
* Both pa and pb must be non-nullptr. */
|
||||
const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb) {
|
||||
// First rewind to the last common height (the forking point cannot be past one of the two).
|
||||
if (pa->nHeight > pb->nHeight) {
|
||||
pa = pa->GetAncestor(pb->nHeight);
|
||||
} else if (pb->nHeight > pa->nHeight) {
|
||||
pb = pb->GetAncestor(pa->nHeight);
|
||||
}
|
||||
|
||||
while (pa != pb && pa && pb) {
|
||||
while (pa != pb) {
|
||||
// Jump back until pa and pb have a common "skip" ancestor.
|
||||
while (pa->pskip != pb->pskip) {
|
||||
// This logic relies on the property that equal-height blocks have equal-height skip
|
||||
// pointers.
|
||||
Assume(pa->nHeight == pb->nHeight);
|
||||
Assume(pa->pskip->nHeight == pb->pskip->nHeight);
|
||||
pa = pa->pskip;
|
||||
pb = pb->pskip;
|
||||
}
|
||||
// At this point, pa and pb are different, but have equal pskip. The forking point lies in
|
||||
// between pa/pb on the one end, and pa->pskip/pb->pskip on the other end.
|
||||
pa = pa->pprev;
|
||||
pb = pb->pprev;
|
||||
}
|
||||
|
||||
// Eventually all chain branches meet at the genesis block.
|
||||
assert(pa == pb);
|
||||
return pa;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue