fix(seidb-bench): stop the state-store bench backends fail on a nil config - #3838
fix(seidb-bench): stop the state-store bench backends fail on a nil config#3838blindchaser wants to merge 1 commit into
Conversation
…nil config runBenchmark hands NewDBImpl a nil dbConfig for every backend, but the SSComposite, SSHistoricalOffload and CompositeDual_SSComposite cases still asserted dbConfig.(*T) without the comma-ok form. A single-value assertion on a nil interface panics, so BenchmarkSSCompositeWrite, BenchmarkSSHistoricalOffloadWrite and BenchmarkCombinedCompositeDualSSComposite crashed at startup — the same failure #3770 fixed for FlatKV, in the same switch. Merely copying that fix would only move the crash one frame later, since both SS Composite constructors dereference the config. Route every case through one generic helper that treats nil as ordinary and only rejects a wrong type, and let the two SS Composite constructors fall back to DefaultBenchStateStoreConfig the way the MemIAVL and FlatKV ones already fall back to theirs. SSHistoricalOffload keeps no default: its stream needs brokers only the caller knows, so it now reports "historical offload config is required" instead of crashing. The first two benchmarks run to completion again; the offload one fails with that message. Co-authored-by: Cursor <cursoragent@cursor.com>
PR SummaryLow Risk Overview Introduces generic Tests are broadened to table-driven coverage: nil opens for backends with defaults, invalid types error per backend, and offload nil is an error not a panic. Reviewed by Cursor Bugbot for commit f9b74de. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
There was a problem hiding this comment.
Benchmark-only fix that correctly collapses three panicking bare type assertions in NewDBImpl into one generic backendConfig[T] helper, with nil-config defaults added to the two SS Composite constructors and table tests covering all five config-taking backends. I found no correctness or security issues; only a minor test-coverage gap and one consistency nit.
Findings: 0 blocking | 4 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
cursor-review.mdis empty — the Cursor pass produced no output, so this review reflects only the Claude and Codex passes (Codex reported no material issues).- The non-config backends (
NoOp,CompositeDual,CompositeSplit,CompositeCosmos) still silently discard a non-nildbConfig. Now that config extraction is centralized inbackendConfig, it would be cheap and consistent to reject a supplied config for those cases too, so a misrouted config surfaces as an error instead of being ignored. Non-blocking, pre-existing behavior. - Pre-existing, worth noting since
backendConfignow returns the caller's pointer verbatim:newFlatKVCommitStoremutates the caller's config (config.DataDir = dbDir) andHistoricalOffloadConfig.Validatemutates the caller's Kafka sub-config viaapplyDefaults. Harmless for bench single-open usage, but a copy-on-entry would make the helper's contract fully read-only. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| require.ErrorContains(t, err, "historical offload config is required") | ||
| } | ||
|
|
||
| func TestNewDBImplRejectsInvalidConfigType(t *testing.T) { |
There was a problem hiding this comment.
[suggestion] The two tables cover the nil path and the wrong-type path, but nothing asserts the third branch of backendConfig — that a correctly-typed non-nil config is passed through and actually honored rather than silently replaced by the backend default. A small case (e.g. open SSComposite with a *config.StateStoreConfig whose EVMSplit/AsyncWriteBuffer differs from DefaultBenchStateStoreConfig(), and assert the store reflects it) would lock in the behavior cryptosim.go:146 depends on when the user supplies a config.
There was a problem hiding this comment.
LGTM — benchmark-only fix, well-tested.
Extended reasoning...
Overview
Two-file change confined to sei-db/state_db/bench/wrappers: a benchmark harness that instantiates DB backends for micro-benchmarking. The PR generalizes the fix from #3770 (nil-config panic on FlatKV) into a single backendConfig[T] generic helper used by all five config-taking cases in NewDBImpl's switch, replacing bare dbConfig.(*T) type assertions that panic on nil interfaces.
Security risks
None. This code only runs under go test/go bench in the benchmark package; it is never invoked from any production binary or RPC path, and touches no auth, crypto, or user-facing input.
Level of scrutiny
Low. Non-production, test/benchmark-only code with a narrow, mechanical fix pattern (replace panic-prone assertions with a helper that treats nil as valid and wrong-type as an error). I verified the one subtlety called out in the description — HistoricalOffloadConfig.Validate() has a nil receiver check (if c == nil { return fmt.Errorf("historical offload config is required") }) — matches the code in historical_offload_wrapper.go, so the claimed non-panic behavior for that backend is correct.
Other factors
Test coverage is thorough: table-driven tests cover nil-config defaulting for every backend that has a default, wrong-type rejection for every backend, and the one backend (SSHistoricalOffload) that intentionally has no default. The diff is small, self-contained, and matches an established prior-fix pattern (#3770) rather than introducing new design decisions.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3838 +/- ##
==========================================
- Coverage 61.29% 60.40% -0.90%
==========================================
Files 2351 2259 -92
Lines 197491 186867 -10624
==========================================
- Hits 121060 112879 -8181
+ Misses 65579 63988 -1591
+ Partials 10852 10000 -852
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Summary
runBenchmarkhandsNewDBImpla nildbConfigfor every backend, but theSSComposite,SSHistoricalOffloadandCompositeDual_SSCompositecases still asserteddbConfig.(*T)in single-value form. That panics on a nil interface, soBenchmarkSSCompositeWrite,BenchmarkSSHistoricalOffloadWriteandBenchmarkCombinedCompositeDualSSCompositeWritecrashed at startup withinterface conversion: interface {} is nil, not *config.StateStoreConfig— the same failure #3770 fixed for FlatKV, in the same switch.Copying that fix case-by-case wouldn't be enough: with only a comma-ok assertion the crash moves one frame later, since both SS Composite constructors dereference
*ssConfig. And this is now the third instance of the same bare-assertion bug in this switch, so the fix collapses config extraction into one place rather than patching instance three.wrappers/db_implementations.go:backendConfig[T]becomes the single path from the untypeddbConfigto a backend's typed config. It treats nil as ordinary — each constructor supplies its own default — and rejects only a wrong type, now naming the type it wanted. All five config-taking cases route through it, so a new backend can't reintroduce the bare assertion.newSSCompositeStateStoreandnewCombinedCompositeDualSSCompositefall back toDefaultBenchStateStoreConfig(), matching the fallback the MemIAVL and FlatKV constructors already have.SSHistoricalOffloaddeliberately keeps no default: its stream needs brokers only the caller knows, so nil reachesHistoricalOffloadConfig.Validate, which already reportshistorical offload config is required.Benchmark-only change; no production code path touched.
Test plan
go test ./sei-db/state_db/bench/wrappers—wrappers_test.gogains two table tests over every config-taking backend: nil resolves to the default and opens, a wrong type errors with the backend named. Plus an offload-specific case asserting the missing config is reported rather than panicked. The two FlatKV-only tests from fix(seidb-bench): tolerate nil FlatKV config in bench wrapper factory #3770 are folded into those tables.main:BenchmarkSSCompositeWrite→panic: interface conversion: interface {} is nil, not *config.StateStoreConfigBenchmarkSSCompositeWrite/100_keys_per_block-11 1 32137667 ns/op 311161 keys/secBenchmarkCombinedCompositeDualSSCompositeWrite/100_keys_per_block-11 1 174587333 ns/op 57278 keys/secBenchmarkSSHistoricalOffloadWritefails withfailed to create historical offload stream: historical offload config is requiredinstead of panicking (it needs a live Kafka broker to actually run)go vet/gofmt -s/goimportsclean