feat(hotblocks): add transaction hash index#93
Merged
Conversation
Add independent EVM transaction hash indexing, lookup APIs, lifecycle cleanup, write-stage metrics, compression sizing, benchmarks, and regression coverage. Co-Authored-By: Codex <codex@openai.com>
7fef7ca to
ec0dd5d
Compare
dzhelezov
added a commit
to dzhelezov/data
that referenced
this pull request
Jul 15, 2026
Broader-instrumentation delta rebased on top of upstream/master (tx/block hash indexes subsquid#93, RocksDB stall metrics subsquid#90, conformance harness). Reconciled against upstream's stall-metric collector (canonical): - upstream RocksDbCollector (intrinsic per-CF/DB-wide property gauges) kept as-is; our duplicate collector + ROCKSDB_CF/DB_PROPERTIES constants and the redundant db.rs int-property/column_families accessors removed. - our unique delta preserved and wired into upstream's collect_rocksdb_metrics: cumulative RocksDB statistics tickers/histograms (block-cache, stalls, bytes, compaction) via encode_rocksdb_statistics + db.rocksdb_statistics(). - slow-response detector (SLOW_RESPONSES/SlowResponseConfig), long_poll TTFB split, per-dataset labels retained as the additive, upstream-PR-able remainder. cargo build + test green (metrics: parses_ticker/histogram + upstream write_duration/per-cf collector tests all pass).
dzhelezov
added a commit
to dzhelezov/data
that referenced
this pull request
Jul 15, 2026
Broader-instrumentation delta rebased on top of upstream/master (tx/block hash indexes subsquid#93, RocksDB stall metrics subsquid#90, conformance harness). Reconciled against upstream's stall-metric collector (canonical): - upstream RocksDbCollector (intrinsic per-CF/DB-wide property gauges) kept as-is; our duplicate collector, property constants, and duplicate storage accessors removed (db.rs is unchanged vs upstream). - our unique delta preserved and wired into upstream's collect_rocksdb_metrics: cumulative RocksDB statistics tickers/histograms (block-cache, stalls, bytes, compaction) via encode_rocksdb_statistics + upstream's db.get_statistics(). - slow-response detector (SLOW_RESPONSES/SlowResponseConfig), long_poll TTFB split, per-dataset labels, write_duration stage timing = additive remainder. nightly rustfmt-clean, clippy correctness-clean, cargo test green (metrics: parses_ticker/histogram + upstream write_duration/per-cf collector tests).
dzhelezov
added a commit
to dzhelezov/data
that referenced
this pull request
Jul 15, 2026
…on (#1) Broader-instrumentation delta rebased on top of upstream/master (tx/block hash indexes subsquid#93, RocksDB stall metrics subsquid#90, conformance harness). Reconciled against upstream's stall-metric collector (canonical): - upstream RocksDbCollector (intrinsic per-CF/DB-wide property gauges) kept as-is; our duplicate collector, property constants, and duplicate storage accessors removed (db.rs is unchanged vs upstream). - our unique delta preserved and wired into upstream's collect_rocksdb_metrics: cumulative RocksDB statistics tickers/histograms (block-cache, stalls, bytes, compaction) via encode_rocksdb_statistics + upstream's db.get_statistics(). - slow-response detector (SLOW_RESPONSES/SlowResponseConfig), long_poll TTFB split, per-dataset labels, write_duration stage timing = additive remainder. nightly rustfmt-clean, clippy correctness-clean, cargo test green (metrics: parses_ticker/histogram + upstream write_duration/per-cf collector tests).
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.
Summary
GET /datasets/{id}/hashes/{hash}/transactionhotblocks_write_duration_seconds{dataset,stage,outcome}forprepare,tables,commit, andretention, with separate nestedblock_hash_indexandtransaction_hash_indexstagesThe index is off by default, independent from the block hash index, and intentionally does not backfill.
Performance
Release-mode Criterion results on the development machine:
Write-stage instrumentation does not update Prometheus per index entry. Storage reads the clock once around each block/transaction index scan, aggregates timings across optimistic-transaction retries, and publishes one histogram observation per completed top-level write after the storage operation returns. The read path is not instrumented by these write metrics.
Disk footprint
A controlled release-mode A/B probe used identical random-looking 32-byte hashes, production key/value encodings, Bloom filters, and full compaction. Figures are live SST bytes for the named CF only, excluding WAL, memtables, and table data:
At one million entries, LZ4 saves only 0.49% for the block index and 0.36% for the transaction index. Use 70–90 B per retained entry as an initial capacity range: approximately 67 GiB per billion blocks and 70 GiB per billion transactions after compaction.
Compression compatibility
Before this PR, the block-index CF used RocksDB default Snappy compression. The A/B difference is too small to justify recompression, so this PR now keeps
BLOCK_HASHESexplicitly on Snappy and configures only the newTRANSACTION_HASHESCF as LZ4.No block-index codec migration, logical migration, or rebuild is required. Existing block SSTs and newly produced block SSTs remain Snappy.
Validation
cargo test -p sqd-storage --lib --test block_hash_index --test transaction_hash_indexcargo test -p sqd-storage --test database_ops --test cleanup_reclaimcargo test -p sqd-storage --lib create_purges_crash_residue_before_publishing_the_dataset_labelcargo test -p sqd-hotblocks --test block_hash_index --test transaction_hash_indexcargo test -p sqd-hotblocks --bin sqd-hotblocks metrics::testscargo test -p sqd-storage --release --lib measure_hash_index_compression_disk_size -- --ignored --nocapturecargo clippy -p sqd-storage -p sqd-hotblocks-harness -p sqd-hotblocks --all-targetscargo +nightly fmt --all -- --checkgit diff --check