Fix flaky evmrpc tests querying blocks before async writes landed - #4218
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4218 +/- ##
==========================================
- Coverage 66.94% 65.88% -1.06%
==========================================
Files 2176 2064 -112
Lines 167157 156077 -11080
==========================================
- Hits 111903 102837 -9066
+ Misses 55113 53099 -2014
Partials 141 141
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
PR SummaryLow Risk Overview Test helpers now call
Reviewed by Cursor Bugbot for commit cfce0c1. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
A well-targeted test-flake fix: draining the state store and following the receipt store's real watermark before serving queries is the correct ordering, and replacing the MaxInt64 receipt pin with the height actually applied makes the RPC watermark honest. No correctness problems found; one suggestion about the silently-optional capability the fix depends on.
Findings: 0 blocking | 2 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- [suggestion]
CompositeStateStore.WaitForPendingWritesis the load-bearing half of this fix but nothing pins it:sei-db/state_db/ss/composite/store.gohas compile-time checks forStateStoreandContextIteratorStore(lines 31-32) andsei-db/state_db/ss/store.gopinsBlockCommitterfor exactly this reason ("a store that loses the method fails the build"). Addingvar _ types.PendingWriteWaiter = (*CompositeStateStore)(nil)alongside them, plus a small case incomposite/store_test.goasserting the delegation reaches both sub-stores, would keep the drain from being dropped unnoticed. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| if err := stateStore.SetLatestVersion(latest); err != nil { | ||
| panic(err) | ||
| if stateStore := a.GetStateStore(); stateStore != nil { | ||
| if w, ok := stateStore.(dbtypes.PendingWriteWaiter); ok { |
There was a problem hiding this comment.
[suggestion] This capability check fails open: if a.GetStateStore() ever returns a store that does not implement PendingWriteWaiter (a new backend, a test double, a rename in sei-db), the drain is silently skipped and the SetLatestVersion pin below advertises a height whose data is not readable — exactly the failure this PR is fixing, with no signal beyond the flake coming back. The receipt branch a few lines down takes the opposite stance and panics with a message naming the versions. Consider matching it here (w, ok := ...; if !ok { panic(...) }), so a store that loses the capability fails the suite loudly instead of quietly reverting to the old behaviour.
The
evmrpc/testssuites commit blocks through the real app and then query the JSON-RPC server straight away, but both stores those queries read from apply their writes in the background. Historical heights are served from the state store, and a handler that encodes a transaction reaches back one height for the base fee and chain config, so if the pebble writer has not yet applied that version the read comes back empty and the request fails, which the test helper surfaces as anilresult and an interface-conversion panic. Since #4159 the receipt store lags the same way, and pinning the receipt watermark toMaxInt64made the RPC layer promise receipts that were not written yet.pinStateStoreLatestVersiononly moved the version marker, which advertises the height without making its data readable, and an injected 200ms delay in the pebble apply loop reproduces every failure in this family deterministically.settleCommittedBlocksnow replaces the pin at both setup choke points (SetupTestServerandSetupBlocks): it drains the state store throughWaitForPendingWrites, whichCompositeStateStoregains by delegating to its cosmos and EVM stores exactly asEVMStateStorealready does for its sub-DBs, and then followsReceiptStore.LatestVersionup to the committed height, the watermark the store documents for readers. The receipt window is pinned to the height actually applied instead ofMaxInt64, so the RPC watermark reflects real visibility. The wait on the receipt writer is bounded because a failed background write latches and would otherwise hang the package until the test timeout.Flaked in: https://github.com/sei-protocol/sei-chain/actions/runs/34646271105/job/103417698875, https://github.com/sei-protocol/sei-chain/actions/runs/34620197535/job/103331963799, https://github.com/sei-protocol/sei-chain/actions/runs/33532797141/job/99939796789, https://github.com/sei-protocol/sei-chain/actions/runs/32806690899/job/97678081007