Repository navigation
Make all page models SSZ compatible for the frontend cache - #915
Conversation
The tiered page cache falls back to JSON and logs "page model not ssz compatible" for models that fail dynssz validation. 14 cached models were affected, through unsized int fields and map fields. - replace int fields with sized integers in the transaction, transactions, address, token, transfers, slot arrival, slot waves and bid-seen models and in the services inclusion-lists view - replace map fields with slices: []UrlParam for the builders and mev blocks pagers, []uint8 filter sets rendered via a new inUint8List template func, a slice with an explicit slot for epoch arrivals and a []*SlotDutyName list for the slot duties endpoint - tag every non-list pointer field in cached models ssz-type:"optional" so nil survives the SSZ round trip; the arrival and waves models no longer need the JSON-path workaround and their nil-fidelity tests now pass on the SSZ path - add cache/page_models_ssz_test.go: registry of all top-level page models with a completeness check, dynssz validation, a zero-value round trip and a static walk requiring the optional tag on every reachable pointer field; handlers/page_models_ssz_test.go covers cached values outside the models package
There was a problem hiding this comment.
Summary
Makes all cached page models SSZ-compatible: sized ints replace unsized ones, maps become slices with updated templates/JS consumers, and every pointer field in cached models gets ssz-type:"optional" so nil survives the round trip, backed by a registry test with a parser-based completeness check. I traced all writers and consumers of the changed fields, verified the template func semantics and the dynssz v1.4.0 optional/pointer behavior, and confirmed stale-JSON cache entries safely fall back to a rebuild. The change looks correct; the only gap is one handler-local cached value (search_ahead) that remains on the JSON path and is missed by the new guard test.
Issues
- 🟢
handlers/page_models_ssz_test.go:25— search_ahead cached value stays on the JSON path, uncovered by the new guard — see the thread on that line
Reviewed @ 7d80953e
"Refactoring is just regret with a roadmap."
This comment has been minimized.
This comment has been minimized.
searchAheadCached held the result as interface{}, which dynssz rejects,
so it stayed on the JSON path. Both of its fields were also tagged
json:"-", so the JSON fallback stored an empty object and every cache hit
answered the search box with null. The value now carries one typed slice
per search type, the handler picks the queried one, and a round-trip
test pins that a cache hit serves the built entries. The type is added
to the handlers SSZ guard.
The models test used go/parser.ParseDir, which staticcheck flags as
deprecated (SA1019); it now parses the package files individually.
There was a problem hiding this comment.
Makes all cached page models SSZ compatible: sized ints, map-to-slice conversions, optional tags on pointer fields, and a typed SSZ-compatible searchAheadCached value replacing the interface{} field that previously cached an empty object on the JSON fallback. The follow-up commit fixes the last open finding — the search-ahead cache value is now covered by the SSZ-compat guard (via the cache's incompatible-type counter, so a dynssz failure fails CI rather than silently falling back to JSON) and by a round-trip test. Demux via result() covers every allowed search type and the JSON response shape is unchanged; error results now persist correctly instead of being cached as empty. No remaining issues found.
Reviewed 48 changed file(s) @ 93817889 — no blocking issues found.
"Refactoring is just regret with a roadmap."
The models registry, completeness check and optional-pointer walk move from the cache package into handlers/page_models_ssz_test.go, which already covered the handler-local cached values through the public cache API, so one test file guards every value handed to the frontend cache.
Summary
The tiered page cache SSZ-encodes page models and silently falls back to JSON (logging
page model not ssz compatible) for models that fail dynssz validation. The transaction page was one of 14 cached models affected. This PR makes every cached model SSZ compatible and adds tests that keep it that way.services.SlotInclusionListsView.[]UrlParamfor the builders and MEV blocks pagers,[]uint8filter sets (rendered via a newinUint8Listtemplate func), a sorted slice with an explicit slot for epoch arrivals, and a[]*SlotDutyNamelist for the slot duties endpoint (the two in-repo JS consumers are updated).ssz-type:"optional"on every non-list pointer in cached models, so nil survives the SSZ round trip. The arrival and waves models were previously kept on the JSON path on the assumption that SSZ had no optionals; the existing nil-fidelity tests now pass on the SSZ path.searchAheadCached) held its result asinterface{}and had both fields taggedjson:"-", so the JSON fallback stored an empty object and cache hits answered the search box withnull. It now carries one typed slice per search type and the handler picks the queried one.Tests
handlers/page_models_ssz_test.go: registry of every value handed to the frontend cache (all top-level page models, checked for completeness against the models package, plus the handler- and service-local cached types). Each is stored through the public cache API and must be counted as SSZ compatible, survive a round trip, and declare every pointer field reachable through nested types as an SSZ optional. A separate round trip pins the search-ahead value.intfield, an unregistered model, an untagged nested pointer).Notes
/validators?jsonnow emitsfilter_cred_typesas an array instead of an object.make api-docsproduced no changes.