Skip to content

feat: add parquet receipt store with DuckDB range queries#2861

Merged
jewei1997 merged 28 commits intomainfrom
parquet-receiptdb2
Feb 17, 2026
Merged

feat: add parquet receipt store with DuckDB range queries#2861
jewei1997 merged 28 commits intomainfrom
parquet-receiptdb2

Conversation

@jewei1997
Copy link
Contributor

@jewei1997 jewei1997 commented Feb 11, 2026

Summary

This PR adds a parquet-based receipt storage backend with DuckDB for efficient range queries on logs, enabling fast eth_getLogs queries across block ranges.

  • Add parquet backend option (Backend: "parquet" in config)
  • Parquet files rotate every 500 blocks
  • DuckDB queries across closed parquet files for efficient log filtering
  • WAL for crash recovery of in-progress parquet files
  • Pruning of old parquet files based on KeepRecent config
  • Build tag support: use -tags duckdb to enable parquet backend

The parquet backend supports the new FilterLogs range query API introduced in #2788, enabling efficient cross-block log queries without falling back to per-receipt fetching.

Dependencies

Test plan

  • Receipt store unit tests pass (without duckdb tag)
  • Parquet store tests pass with -tags duckdb
  • Integration testing with full node using parquet backend

@github-actions
Copy link

github-actions bot commented Feb 11, 2026

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 17, 2026, 5:44 PM

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 71.16858% with 301 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.32%. Comparing base (ccf65fa) to head (fc71aad).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
sei-db/ledger_db/parquet/store.go 66.44% 56 Missing and 43 partials ⚠️
sei-db/ledger_db/receipt/parquet_store.go 65.53% 62 Missing and 29 partials ⚠️
sei-db/ledger_db/parquet/reader.go 73.26% 48 Missing and 25 partials ⚠️
sei-db/ledger_db/receipt/receipt_cache.go 79.54% 10 Missing and 8 partials ⚠️
sei-db/ledger_db/parquet/wal.go 75.38% 8 Missing and 8 partials ⚠️
sei-db/ledger_db/receipt/cached_receipt_store.go 95.91% 1 Missing and 1 partial ⚠️
sei-db/ledger_db/receipt/receipt_store.go 80.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #2861       +/-   ##
===========================================
+ Coverage   48.36%   57.32%    +8.95%     
===========================================
  Files         671     2097     +1426     
  Lines       50621   172767   +122146     
===========================================
+ Hits        24485    99032    +74547     
- Misses      23988    64850    +40862     
- Partials     2148     8885     +6737     
Flag Coverage Δ
sei-chain 52.82% <71.16%> (?)
sei-cosmos 48.19% <ø> (+<0.01%) ⬆️
sei-db 68.72% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
evmrpc/filter.go 69.07% <ø> (ø)
sei-db/ledger_db/receipt/cached_receipt_store.go 92.30% <95.91%> (ø)
sei-db/ledger_db/receipt/receipt_store.go 76.96% <80.00%> (ø)
sei-db/ledger_db/parquet/wal.go 75.38% <75.38%> (ø)
sei-db/ledger_db/receipt/receipt_cache.go 81.11% <79.54%> (ø)
sei-db/ledger_db/parquet/reader.go 73.26% <73.26%> (ø)
sei-db/ledger_db/receipt/parquet_store.go 65.53% <65.53%> (ø)
sei-db/ledger_db/parquet/store.go 66.44% <66.44%> (ø)

... and 1543 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines +230 to +240
for blockNum, logs := range chunk.logs {
if blockNum < fromBlock || blockNum > toBlock {
continue
}
for _, lg := range logs {
if matchLog(lg, crit) {
logCopy := *lg
result = append(result, &logCopy)
}
}
}

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism
"database/sql"
"fmt"
"path/filepath"
"runtime"

Check notice

Code scanning / CodeQL

Sensitive package import Note

Certain system packages contain functions which may be a possible source of non-determinism
Comment on lines +310 to +332
go func() {
for {
latestVersion := s.latestVersion.Load()
pruneBeforeBlock := latestVersion - s.config.KeepRecent
if pruneBeforeBlock > 0 {
pruned := s.pruneOldFiles(uint64(pruneBeforeBlock))
if pruned > 0 && s.log != nil {
s.log.Info(fmt.Sprintf("Pruned %d parquet file pairs older than block %d", pruned, pruneBeforeBlock))
}
}

// Add jitter to avoid thundering herd
jitter := time.Duration(float64(pruneIntervalSeconds)*0.5) * time.Second
sleepDuration := time.Duration(pruneIntervalSeconds)*time.Second + jitter

select {
case <-s.pruneStop:
return
case <-time.After(sleepDuration):
// Continue to next iteration
}
}
}()

Check notice

Code scanning / CodeQL

Spawning a Go routine Note

Spawning a Go routine may be a possible source of non-determinism
}

// Add random jitter (up to 50% of base interval) to avoid thundering herd
jitter := time.Duration(rand.Float64()*float64(pruneIntervalSeconds)*0.5) * time.Second

Check notice

Code scanning / CodeQL

Floating point arithmetic Note

Floating point arithmetic operations are not associative and a possible source of non-determinism
}

// Add random jitter (up to 50% of base interval) to avoid thundering herd
jitter := time.Duration(rand.Float64()*float64(pruneIntervalSeconds)*0.5) * time.Second

Check notice

Code scanning / CodeQL

Floating point arithmetic Note

Floating point arithmetic operations are not associative and a possible source of non-determinism
@jewei1997 jewei1997 merged commit ca2a7c8 into main Feb 17, 2026
41 of 42 checks passed
@jewei1997 jewei1997 deleted the parquet-receiptdb2 branch February 17, 2026 19:18
jewei1997 added a commit that referenced this pull request Feb 24, 2026
## Summary

This PR adds a parquet-based receipt storage backend with DuckDB for
efficient range queries on logs, enabling fast `eth_getLogs` queries
across block ranges.

- Add parquet backend option (`Backend: "parquet"` in config)
- Parquet files rotate every 500 blocks
- DuckDB queries across closed parquet files for efficient log filtering
- WAL for crash recovery of in-progress parquet files
- Pruning of old parquet files based on `KeepRecent` config
- Build tag support: use `-tags duckdb` to enable parquet backend

The parquet backend supports the new `FilterLogs` range query API
introduced in #2788, enabling efficient cross-block log queries without
falling back to per-receipt fetching.

## Dependencies

- Depends on #2788 (ledger cache layer)

## Test plan

- Receipt store unit tests pass (without duckdb tag)
- Parquet store tests pass with `-tags duckdb`
- Integration testing with full node using parquet backend
yzang2019 pushed a commit that referenced this pull request Feb 25, 2026
This PR adds a parquet-based receipt storage backend with DuckDB for
efficient range queries on logs, enabling fast `eth_getLogs` queries
across block ranges.

- Add parquet backend option (`Backend: "parquet"` in config)
- Parquet files rotate every 500 blocks
- DuckDB queries across closed parquet files for efficient log filtering
- WAL for crash recovery of in-progress parquet files
- Pruning of old parquet files based on `KeepRecent` config
- Build tag support: use `-tags duckdb` to enable parquet backend

The parquet backend supports the new `FilterLogs` range query API
introduced in #2788, enabling efficient cross-block log queries without
falling back to per-receipt fetching.

- Depends on #2788 (ledger cache layer)

- Receipt store unit tests pass (without duckdb tag)
- Parquet store tests pass with `-tags duckdb`
- Integration testing with full node using parquet backend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants