rpc/jsonrpc: test the receipt cache against physically retired history - #23871
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Retirement waits need bounded contexts to prevent package-wide stalls.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds integration coverage proving receipt-gated RPC endpoints work after state history is physically retired.
Changes:
- Adds a physically pruned PoS-chain fixture.
- Tests receipt-cache and no-cache behavior across 14 endpoints.
- Extracts shared API construction.
File summaries
| File | Description |
|---|---|
rpc/jsonrpc/prune_gating_test.go |
Adds the pruning fixture and shared endpoint helpers. |
rpc/jsonrpc/check_prune_gates_test.go |
Adds positive and negative receipt-cache tests. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // advances, so the chain is PoS and the forkchoice is driven block by block. | ||
| func setupPhysicallyPrunedHistory(t *testing.T, cfg prunedHistoryConfig) (pruneGatingAPIs, pruneGatingChain) { | ||
| t.Helper() | ||
| ctx := t.Context() |
|
Ran both tests three times, stable. Checked the two things the design rests on and they hold: The negative test does not test the fixture — it tests arithmetic. With the cache off the gate takes the first branch of The same applies to the precondition in the positive test. The negative test also moves the receipt retention, not just the cache. The positive one passes Both are about what the tests claim rather than whether they pass. Neither blocks. |
Bound the retirement waits in setupPhysicallyPrunedHistory to one minute, matching the existing execmodule retirement tests. t.Context() is cancelled only after the test ends, so a missed retirement notification would stall the whole package until the suite-wide timeout instead of failing that test. Correct what the two receipt tests claim. With the cache off the gate takes the !persisted branch of checkReceiptSourceAvailable and lands in checkPruneHistory, one window comparison that reads neither HistoryStartFrom nor any file, so the negative test is the control that attributes the positive test's answers to the cache, not the leg that proves the fixture is retired. The same arithmetic serves the GetBalance precondition; the disk-level guarantee is requireRetiredAbove, which already runs in the shared fixture. Set Receipts: KeepAllReceiptsPruneMode in the negative test too. An unset field resolves to KeepAllBlocksPruneMode, the follow-history default rather than force-keep-all; the outcome is unchanged today only because PersistReceipts.Enabled short-circuits before ReceiptsAmount() is read, which makes the comparison controlled by accident of gate ordering.
|
@AskAlexSharov All 3 points are addressed |
Follow-up to #23322, closing the half of
r3880873497 that
#23759 left open. Test-only change.
setupPruneGatingstores the prune mode without pruning anything, so a cell asserting that akeep-all receipt retention still serves an old block can be answered by re-execution. #23759
added
requirePersistedReceipts, which proves the cache holds the receipts, but not that thecache is what the endpoint reads.
New fixture
setupPhysicallyPrunedHistoryretires state history on disk: a PoS chain with asmall step size, driven block by block through the forkchoice so finality advances and state
files are built and retired.
requireRetiredAbovepins the precondition —HistoryStartFrom(kv.AccountsDomain)above the block under test — so re-execution has nostate to start from.
Two tests over the 14 endpoints gated on receipts:
TestReceiptCacheServesBlocksWhoseHistoryIsRetiredTestReceiptsWithoutCacheStopAtRetiredHistorystate.PrunedErrorThe second is what makes the first mean something: without it the availability leg would pass
on any datadir.
newPruneGatingAPIsis extracted fromsetupPruneGatingunchanged and sharedby both fixtures.
Not covered
The shape where the cache is retired alongside history: enabling it needs
statecfg.EnableHistoricalRCache(), which mutates the package-level schema and so changes theoutcome of other tests in this binary.
Verification
go test ./rpc/jsonrpc/green (45s, the new tests ~3s each),make lintclean.