[r3.6] docs(site): Caplin v3.6 block production, and correct the disk-storage claim - #23587
Conversation
The intro said Caplin "eliminates the need for separate disk storage", while the same page documents <datadir>/caplin/indexing and Caplin snapshots. Caplin does write to disk; every one of its directories is built under the single Erigon datadir (db/datadir/dirs.go:119-128, SnapDir = "snapshots" at :95). What it removes is a second client process and a second datadir, not the storage.
Adds a "Block Production Behaviour" section to the Caplin staking page for the three v3.6 changes an operator can see or act on. Payload preparation (#23437): cl/beacon/handler/payload_preparation.go :158 targets current slot + 1, :230-232 caps the lead at one slot, and :112-127 gates the whole loop on the Beacon API `validator` namespace (cl/beacon/beacon_router_configuration/cfg.go:66-67), on a registered fee recipient (:175-178, :278), and on an engine implementing PayloadBuilder. Only ExecutionClientDirect does (cl/phase1/execution_client/execution_client_direct.go:152), so --caplin.use-engine-api (cmd/utils/flags.go:930) selects ExecutionClientEngineLocal (node/eth/backend.go:1019) and preparation is skipped. Gloas/pre-Capella skips at :162-167; log lines at :137, :329. Fork-choice head before the state copy (#23172): published at cl/phase1/forkchoice/get_head.go:113 via cl/phase1/stages/forkchoice.go :42; the copy happens later at forkchoice.go:345 -> cl/beacon/synced_data/synced_data.go:152-161. Read path cl/beacon/handler/handler.go:499-509 still 503s while syncing. Default graffiti (#22303): cl/beacon/handler/block_production.go:95-104 builds <EL code><EL commit><CN><CL commit>; codes and prefixes at :83-85, :168-190; expected strings pinned in block_production_graffiti_test.go:117-160. There is no graffiti CLI flag anywhere in the tree; the only override is the `graffiti` query parameter at :590-595, read as a 32-byte hex value. Left out deliberately: the txpool deadlock fix (#23360) is a pure locking change in txnprovider/txpool/pool.go with no flag, default or metric, so there is nothing for an operator to do; and "boundary attestations accepted while the head state lags" is not a v3.6 change — it shipped in v3.5.1 via #22251. llms-full.txt regenerated by docs/site/scripts/generate-llms.py.
…aims `--caplin.use-engine-api` does not merely skip payload preparation: it returns early from `setBeaconAPI`, so the whole Beacon API is disabled and Caplin cannot stake at all in that mode. Framing the cost as a skipped optimisation invited a staker to turn it on. It is also not silent — a warning is logged when `--beacon.api` is set alongside it. The debug fork-choice endpoint never read head state, so it was not delayed by the state copy and gains nothing here; the endpoint that does is `/eth/v2/debug/beacon/heads`. The graffiti query parameter is honoured on the v2, v3 and v4 validator block endpoints, and it is not validated: a malformed or empty value yields an all-zero graffiti rather than falling back to the default.
|
Corrected in Two of them were wrong, one materially:
What held up on re-check: the three One nuance worth recording: payload preparation and the fork-choice publish are not in
|
There was a problem hiding this comment.
Pull request overview
Updates Caplin documentation for the v3.6 release line, focusing on operator-visible block production behavior changes and correcting an inaccurate “no disk storage” claim. This fits into the docs site’s Caplin fundamentals and staking guidance, and updates the pre-rendered llms-full.txt artifacts accordingly.
Changes:
- Replace marketing-style Caplin intro text with an accurate description of process/datadir unification while clarifying that Caplin still writes to disk (indexing DB + snapshots + related subdirs).
- Add a “Block Production Behaviour” section documenting v3.6 proposal-path behavior: one-slot-ahead payload preparation (with real preconditions), earlier fork-choice head publication, and default client-pair graffiti behavior/overrides.
- Mirror these doc updates into the
llms-full.txtanddocs/site/static/llms-full.txtartifacts.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| llms-full.txt | Updates embedded docs snapshots: Caplin fundamentals intro + new v3.6 block production behavior section. |
| docs/site/static/llms-full.txt | Same as llms-full.txt, for the docs site’s static bundle. |
| docs/site/docs/staking/caplin.md | Adds v3.6 block production behavior documentation (payload prep, head publication timing, default graffiti). |
| docs/site/docs/fundamentals/caplin.md | Corrects Caplin “disk storage” claim and replaces marketing prose with accurate storage/process statements. |
Suppressed comments (3)
docs/site/docs/staking/caplin.md:110
- The endpoint list is a bit ambiguous as written (it reads like "/eth/v4 /validator/blocks/{slot}"). Spell out the full paths to avoid confusion.
There is no CLI flag for graffiti. The only way to override it is per block, through the Beacon API: a validator client that sends a `graffiti` query parameter on the validator block-production endpoints (`GET /eth/v2`, `/eth/v3` or `/eth/v4` `/validator/blocks/{slot}`) has its value used instead of the default. The parameter is read as a 32-byte hex value, as the Beacon API specification requires. It is not validated: a malformed or empty value is not rejected and does not fall back to the default — it silently produces an all-zero graffiti. A shorter hex value is left-padded with zeros, and a longer one is cropped from the left. Note that a validator client which sets graffiti by default — including its own client string — overrides Caplin's default; to get the client-pair graffiti, leave the validator client's graffiti unset.
llms-full.txt:7726
- The endpoint list is a bit ambiguous as written (it reads like "/eth/v4 /validator/blocks/{slot}"). Spell out the full paths to avoid confusion.
There is no CLI flag for graffiti. The only way to override it is per block, through the Beacon API: a validator client that sends a `graffiti` query parameter on the validator block-production endpoints (`GET /eth/v2`, `/eth/v3` or `/eth/v4` `/validator/blocks/{slot}`) has its value used instead of the default. The parameter is read as a 32-byte hex value, as the Beacon API specification requires. It is not validated: a malformed or empty value is not rejected and does not fall back to the default — it silently produces an all-zero graffiti. A shorter hex value is left-padded with zeros, and a longer one is cropped from the left. Note that a validator client which sets graffiti by default — including its own client string — overrides Caplin's default; to get the client-pair graffiti, leave the validator client's graffiti unset.
docs/site/static/llms-full.txt:7726
- The endpoint list is a bit ambiguous as written (it reads like "/eth/v4 /validator/blocks/{slot}"). Spell out the full paths to avoid confusion.
There is no CLI flag for graffiti. The only way to override it is per block, through the Beacon API: a validator client that sends a `graffiti` query parameter on the validator block-production endpoints (`GET /eth/v2`, `/eth/v3` or `/eth/v4` `/validator/blocks/{slot}`) has its value used instead of the default. The parameter is read as a 32-byte hex value, as the Beacon API specification requires. It is not validated: a malformed or empty value is not rejected and does not fall back to the default — it silently produces an all-zero graffiti. A shorter hex value is left-padded with zeros, and a longer one is cropped from the left. Note that a validator client which sets graffiti by default — including its own client string — overrides Caplin's default; to get the client-pair graffiti, leave the validator client's graffiti unset.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…a sentence The graffiti override listed the endpoint versions and the path separately, which read as two paths rather than three versions of one. Each is now written in full, and the deprecated v2 route is marked as such.
yperbasis
left a comment
There was a problem hiding this comment.
One attribution claim is inaccurate when an external builder wins. Please update it before merge.
…ad builder defaultGraffiti reads the locally connected execution client. When an external builder's bid wins, produceBlock blinds the already-built beacon body and swaps in the builder's execution header, so that graffiti still names the proposing node's own clients.
Two Caplin doc fixes for v3.6, both traced to code on
release/3.6.Block production (
/staking/caplin) — the page had nothing on the v3.6 proposal path. Adds the three operator-visible changes:validatornamespace, a registered fee recipient, and Caplin driving the in-process execution layer.--caplin.use-engine-apiswitches Caplin to the Engine API, whereStartPayloadBuildis unimplemented and preparation is skipped.engine_getClientVersionV1is still uncached, and a validator client that sets its own graffiti overrides the default. There is no graffiti CLI flag; the only override is the Beacon APIgraffitiquery parameter, listed against all three validator block endpoints.Disk storage (
/fundamentals/caplin) — corrects the storage claim.