fix(archiver): speed up log-by-tag queries - #25254
Open
spalladino wants to merge 4 commits into
Open
Conversation
Queries that omit referenceBlock now pin themselves to the current chain tip: the tip caps every per-tag scan and is re-checked after the scans, and a query whose anchor is unwound mid-flight is re-run against the new tip (3 attempts) instead of returning a torn read. Explicit-referenceBlock queries keep throwing the reorg error as before.
Tag log queries run inside db.transactionAsync again, so they serialize with queued writes by design and cannot return a torn result; the implicit self-anchoring and post-scan anchor re-check are dropped. The optimizations that do not change consistency semantics are kept: 8-wide parallel per-tag scans, and one-page cursor reads for bounded scans (now also reached from inside a write transaction whose batches are empty).
Collaborator
Flakey Tests🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
getPrivateLogsByTagswas reported at 100-200ms per call in production, ~10x slower than other node RPC calls. The existingnode_rpc_perfbench couldn't see it (~0.2ms) because it measured a single random tag; measured PXE traffic at the node boundary is very different: ~100 tags per call (median 84, p95 100),includeEffectson, nofromBlock, and a near-total miss rate (0.45% of tags match; 86% of calls return nothing). Profiling with representative benches attributed the cost to: per-tag scans running sequentially, each paying 2-4 native msgpack cursor round trips (10-entry pages vs a 20-log limit); queries queueing behind writes on lmdb-v2's single writer queue; and, for log-heavy responses, re-hydrating thousands ofFrfields through layered Zod schemas and a Buffer-to-hex-to-BigInt round trip.Approach
Queries stay transactional: they still run in
db.transactionAsyncwith exactly the same snapshot-consistency semantics as before (and therefore still serialize with writes — an earlier revision of this PR moved them off the writer queue and was deliberately rolled back to keep the consistency guarantee; making writes faster is the follow-up lever for contended latency).Within that unchanged envelope:
asyncPoolover the transaction's snapshot instead of one at a time, preserving per-tag result order.limit <= 128are fetched as a single one-page cursor request (one native round trip, no cursor slot held). A narrow fast path inWriteTransaction.iteratedelegates to that one-page read when the pending batch is empty — safe because nothing pending can shadow or suppress a committed entry — so it also applies to reads inside a transaction.hexSchemaForcollapses its refine/refine/transform chain into a single transform, andfromHexStringbuilds field elements viaBigInt('0x…')directly instead of round-tripping through a Buffer (~5x faster per field, benefits all hex deserialization).Measured impact (uncontended, vs base):
includeEffects), in-process: 5.3ms → 3.2ms (~40%).Benches and tests added:
node_rpc_perfbench now mints to private so blocks contain real private logs, and addsgetPrivateLogsByTags_100tagsshaped after the measured recipient-sync traffic (100 tags, 1 hit + 99 misses,includeEffects,referenceBlock; ~3.4ms avg) plusgetPrivateLogsByTags_100tags_allhitsandgetPublicLogsByTags_100tagsstress variants, alongside the existing single-tag series.node_rpc_private_logs_perfbench: in-process vs HTTP matrix with real vs random tags, control calls, and a queueing contention probe.log_store_write_contentiontest: asserts a tag query racing queued write transactions returns results identical to an uncontended query.