erigontech / erigontech/erigon

db/kv, db/state: add an additive RangeReader interface and fold in the harness range machinery

Open
#22,550 2 comments 1 reaction 0 assignees View on GitHub
ErigonDB
Dominant language
Go
Stars
3.6k
Forks
1.5k
Avg merge
1d 16h
Merged PRs (30d)
455

Description

## Motivation

#22467 introduced `membatchwithdb.DomainReader` — an overlay→SharedDomains bridge for **point** domain reads (`GetAsOf`, `HistorySeek`), wired via `overlay.DomainReader = sd`. It's the clean mechanism for making overlay read views observe in-flight (not-yet-committed) tip state.

#21414 converged on `DomainReader` for point reads, but it still carries a **separate** in-memory range/history/index machinery for the RPC test harness, because `DomainReader` does not cover those methods:

- `SharedDomains.RangeAsOf` / `HistoryRange` / `IndexRange` (+ `TemporalMemBatch` helpers: `memRangeAsOf`, `memHistoryRange`, `memIndexTxNums`, `iiMem`, `liveLimitKV`, …)
- the harness `OverlayDB` / `sdRoTx` wrapper that routes RPC reads through those.

So today there are two overlapping overlay-read mechanisms: `DomainReader` (point reads) and the harness range machinery (range/history/index).

## Proposal — additive `RangeReader`, not a fattened `DomainReader`

Keep `DomainReader` focused on point reads and add a **separate, additive** interface for the range/history/index surface (interface segregation — a consumer implements only what it serves):

```go
type RangeReader interface {
RangeAsOf(ctx, domain, fromKey, toKey, ts, asc, limit, roTx) (stream.KV, error)
HistoryRange(ctx, domain, fromTs, toTs, asc, limit, roTx) (stream.KV, error)
IndexRange(name, k, fromTs, toTs, asc, limit, roTx) (stream.U64, error)
}
```

- `MemoryMutation` gains an optional `RangeReader` field alongside `DomainReader`; `overlay.RangeReader = sd` wires the SD (which already implements these).
- The overlay/read-view range methods route through `RangeReader` when set, exactly as point reads route through `DomainReader`.
- (Latest reads `GetLatest`/`HasPrefix` can join `DomainReader` or a small `LatestReader` — decide when wiring.)

Then the harness `OverlayDB`/`sdRoTx` and the standalone `SharedDomains.RangeAsOf`/`HistoryRange`/`IndexRange` delegations fold into the `RangeReader` path, removing the duplicate mechanism. `DomainReader` stays small; nothing that only needs point reads has to grow.

## Scope / sequencing

Do this alongside (or after) the bg-commit-default flip, where in-flight range reads actually matter. Until then #21414 keeps the range machinery as-is. Relates to #21414 (converged on `DomainReader` for point reads), #22467 (introduced `DomainReader`), #22520 (SD run-task worker), #21314 (SD-aware consumers).

Contributor guide

Open the contributing guide

Research direction

Start with MemoryMutation and DomainReader, then trace SharedDomains.RangeAsOf, HistoryRange, and IndexRange through the overlay/read-view paths. Inspect the harness OverlayDB and sdRoTx wrappers to understand the duplicate range machinery. Done means range, history, and index reads use the optional RangeReader path while DomainReader remains focused on point reads.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend-api-design, databases
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.