You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(rpc): resolve block records by binary search, not by walking the chain
Context::record_for_hash walked every record in the block log to find one. The
log holds one entry per applied block and nothing removes it, so at a mainnet tip
that is ~963k comparisons per call -- and getblock, getblockheader and the index
read path all land there. It is the same shape as the gettxoutproof scan, on a
hotter path.
Step 1 already knows the height, because the block tree gave it. That makes the
lookup a binary search over a height-ordered log. The log is append-only in
height order -- add_block pushes, and the only removal is the tail pop a
disconnect performs on the applied tip -- and the codebase already relied on that:
crates/node had record_at_height and record_at_height_hash doing exactly this.
Rather than copy them, they move to crates/rpc beside BlockRecord and node imports
them, so one implementation serves both and forty lines of duplicate go away.
Context::block_by_height and Context::block_hash_at_height were scanning the same
way and now use them too.
Step 2 stays linear on purpose. Without the tree there is no height to search on,
and a hash-keyed index would have to be maintained for every block to serve a path
only legacy state reaches. The comment says so.
Three tests cover the parts the rpc side never had: that a hash is matched within
a duplicate-height run rather than the run's first record being assumed, that a
hash absent from the run does not resolve to a sibling, and that a log which does
not start at height zero still resolves.
The duplicate-height test is shaped deliberately. Heights [1, 1, 2] put the dense
fast path's index straight onto the second duplicate, where the height check alone
would accept it and only the preceding-record guard rejects it. An earlier version
used heights starting at zero, passed, and did not touch the guard at all -- the
mutation audit caught that the test was not testing what its name claimed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments