perf(drive-abci): fetch the next core height's masternode and quorum lists ahead of time - #4556
Conversation
…lists ahead of time Replaying history, about two thirds of mainnet blocks advance the core chain-locked height by one, and each of those blocks waits on protx listdiff and then quorum listextended — together about a millisecond of the seven a block costs, nearly all of it Core's round trip. The heights are consecutive, so start the next pair as soon as the current one returns, on a second connection so a speculative call never sits in front of a real one. A guess that fails — the normal case at the tip, where the next core block does not exist yet — backs the prefetcher off for the next 32 calls instead of asking again every block. A node that cannot open the second connection logs a warning and runs without prefetching.
|
Warning Review limit reachedNext included review available in 17 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🕓 Ready for review — 17 ahead in queue (commit 5dee747) |
|
Superseded by #4572, which is the same change from a branch in 🤖 Posted autonomously by Claude on behalf of pasta. |
Issue being fixed or feature implemented
Replaying history, about two thirds of mainnet blocks advance the core chain-locked height by one, and each of those blocks blocks on two Core RPCs in turn:
protx listdifffor the masternode diff, thenquorum listextended.Measured replaying mainnet with per-block phase timing:
core_infototalprotx listdiffquorum listextendedSo ~0.96 ms of the ~7 ms a block costs is drive-abci sitting on a Core round trip, and Core has spare capacity while it waits.
What was done?
The heights are consecutive, so start the next pair as soon as the current one returns.
A
CorePrefetcherholds one in-flight speculative fetch of each kind, keyed on the height (and base height, for the diff) it was started for.get_quorum_listextendedandget_protx_diff_with_masternodestake the speculative answer when the key matches what they were asked for, and start the next guess either way. A key mismatch falls through to a real call, so a wrong guess costs nothing but a discarded response.Two things keep it from misbehaving at the tip, where the next core block does not exist yet:
jsonrpc's HTTP transport serialises requests behind a single socket mutex, so sharing the connection would defeat the point.A node that cannot open the second connection logs a warning and runs without prefetching.
How Has This Been Tested?
Interleaved A/B on a fixed window at mainnet height 190k, four runs alternating:
core_inforpc_protx_diff682 → 514 µs,rpc_quorum_list670 → 470 µs. Note these runs shared onedashdwith two other syncing nodes, so the residual wait is partly RPC contention from the harness rather than a limit of the approach.Also exercised across a full mainnet replay, genesis to 424,981, with every committed app hash matching a reference sync.
cargo test -p drive-abci --lib— 2,770 passed.Breaking Changes
None. One extra Core RPC connection per node, and speculative requests that Core answers from data it already has.
Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code