Skip to content

Improve LastCommonAncestor performance + add tests - #33515

Merged
achow101 merged 2 commits into
bitcoin:masterfrom
sipa:202510_lca
Oct 7, 2025
Merged

Improve LastCommonAncestor performance + add tests#33515
achow101 merged 2 commits into
bitcoin:masterfrom
sipa:202510_lca

Conversation

@sipa

@sipa sipa commented Oct 1, 2025

Copy link
Copy Markdown
Member

In theory, the LastCommonAncestor function in chain.cpp can take $\mathcal{O}(n)$ time, walking over the entire chain, if the forking point is very early, which could take ~milliseconds. I expect this to be very rare in normal occurrences, but it seems nontrivial to reason about worst cases as it's accessible from several places in net_processing.

This PR modifies the algorithm to make use of the CBlockIndex::pskip skip pointers to find the forking point in sublinear time (a simulation shows that for heights up to $34 \cdot 4^k - 2$ and $k \geq 8$, no more than $k^2 + 10k + 13$ steps are ever needed), in a way that should be nearly free - at worst the same number of memory accesses should be made, with a tiny increase in computation.

As it appears we didn't really have tests for this function, unit tests are added for that function as well as CBlockIndex::GetAncestor().

This is inspired by #32180 (comment)

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants