PORTING OF PR #22919 to main - #23675
Conversation
#22915 trimmed the README from 721 to 221 lines on the understanding that #22919 had moved the content onto the site. #22919 only ever landed on release/3.5, so on main this material is now in neither place. This adds it, re-derived against main's source. Hardware Requirements regains the Filesystem section (ext4/XFS, noatime mount, why latency is the bottleneck, why ZFS and Btrfs are the wrong shape for this workload) and Sync Times. The Overview table was recommending RAID 0 and floating ZFS for archive nodes, which the Filesystem section contradicts; its Disk Type and CPU rows also had two missing line breaks. The section also covers the startup check added in #23524, which warns per filesystem type behind Erigon's directories and links readers to this page -- a page that until now said nothing about filesystems. The note records that it is a warning rather than a refusal, and that an undetectable type is logged at debug level, so silence is not proof of ext4 or XFS. The Hetzner note claimed a stateless firewall for both product lines -- Cloud is stateful, and adding outbound rules there flips outbound to implicit deny and breaks the snapshot download. Its port table listed 9000 for Caplin, which is Lighthouse's default; Caplin's own are 4000 UDP and 4001 TCP (caplin.discovery.port, caplin.discovery.tcpport), and the downloader's 42069 was missing entirely. Also adds the reserved-IPv4 list worth blocking so outbound dials do not trip Hetzner's abuse detection, and SIGABRT for a wedged node. Env vars: document that Erigon accepts its own variables with or without the ERIGON_ prefix, warns when it reads the bare name, and that the Docker ones do not take it -- the examples now use the prefixed form. Also the torrent.log verbosity rule, the Beacon API's ~6 GB RAM cost, make DIST=... install for running outside the build tree, and what --batchSize does to MDBX growth.
There was a problem hiding this comment.
🟡 Changes recommended
It contains a couple of documentation statements that don’t match the codebase behavior (signal choice for stack dumping, env-var warning semantics, and an RFC citation mismatch).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Restores operator/developer guidance that was dropped from README.md under the assumption it had moved to docs.erigon.tech, and fills gaps in the site docs around filesystem recommendations, sync times, Hetzner firewall behavior, and several operational tips; then regenerates llms-full.txt outputs accordingly.
Changes:
- Add a Filesystem section and Sync Times back to Hardware Requirements (and align storage guidance across related pages).
- Expand Troubleshooting with Hetzner Cloud vs Robot firewall behavior, reserved IPv4 ranges, and a “wedged node” kill signal.
- Document env-var prefix behavior, downloader
torrent.logverbosity routing, Caplin Beacon API RAM overhead, andmake DIST=… install.
File summaries
| File | Description |
|---|---|
| llms-full.txt | Regenerated full-site LLM export reflecting the restored guidance. |
| docs/site/static/llms-full.txt | Same regenerated LLM export under the docs site static tree. |
| docs/site/docs/get-started/hardware-requirements.mdx | Adds filesystem recommendations + rationale and restores sync-time estimates. |
| docs/site/help-center/troubleshooting.md | Updates Hetzner firewall note, adds reserved-range blocklist, and adds “wedged node” signal guidance. |
| docs/site/docs/get-started/installation/index.mdx | Adds make DIST=… install guidance and clarifies running from build tree vs installed path. |
| docs/site/docs/fundamentals/security.md | Adds cross-link to Hetzner firewall note. |
| docs/site/docs/fundamentals/optimizing-storage.md | Updates storage recommendation to single NVMe + ext4/XFS and links to Filesystem section. |
| docs/site/docs/fundamentals/performance-tricks.md | Switches examples to ERIGON_-prefixed env var form. |
| docs/site/docs/fundamentals/multiple-instances.md | Improves NAS tuning section and updates env var name and example flags. |
| docs/site/docs/fundamentals/logs.md | Adds downloader logs/torrent.log behavior explanation. |
| docs/site/docs/fundamentals/database.md | Adds note about --batchSize affecting MDBX growth high-water mark behavior. |
| docs/site/docs/fundamentals/configuring-erigon.mdx | Adds env-var prefix guidance and updates examples to ERIGON_ form. |
| docs/site/docs/fundamentals/caplin.md | Adds Beacon API enablement note and ~6GB RAM overhead callout. |
Review details
- Files reviewed: 13/13 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…caveat - Recommend SIGQUIT rather than SIGABRT for a wedged node. Erigon wires a handler only for SIGUSR1 (node/debug/signal-unix.go), so the signal falls through to the Go runtime, and SIGQUIT is what dumps every goroutine stack -- the behaviour this repo's own CI watchdog relies on. - The ERIGON_ prefix does not silence the env-var warning. envLookup logs every variable it reads at warn level; the bare name only draws an extra "use ERIGON_ prefix for env" line on top. - Say up front that the reserved-IPv4 list is an IANA reference rather than a ruleset to paste, and that 127.0.0.0/8 and 255.255.255.255/32 must stay out of an outbound drop rule -- the reason was only given after the list. - Mark 192.88.99.0/24 deprecated in the table and cite RFC 7526 alongside RFC 3068, matching the prose above it.
There was a problem hiding this comment.
🟢 Approval recommended
Changes are documentation-only and the updated claims about runtime behavior (filesystem warning URL/log level, env-var prefix logging, Caplin ports/defaults) match the referenced code paths.
Review details
- Files reviewed: 13/13 changed files
- Comments generated: 0 new
- Review effort level: Lite
listenSignalsInner also takes SIGINT and SIGTERM. The point that matters for a wedged node is narrower: there is no SIGQUIT handler, so SIGQUIT reaches the Go runtime and gets its default all-goroutine dump.
The web edit dropped the Cloud Storage Considerations section but could not rerun the generator, so docs-site / build went red on the llms drift check. Regenerated; no prose changes.
- Robot is stateless, so listening ports alone are not enough: replies to Erigon's own DNS, webseed HTTPS and outgoing peer dials land on ephemeral local ports and need inbound rules of their own. Point at Hetzner's own stateless-firewall notes rather than implying a Cloud ruleset ports over. - The linked iptables list is no longer presented as safe to paste. It omits 127.0.0.0/8 deliberately, but 240.0.0.0/4 already spans 255.255.255.255 so the old "leaves limited broadcast unblocked" claim was wrong, and a blanket OUTPUT drop takes out 169.254.169.254 — Hetzner Cloud's metadata endpoint — along with private-network and multicast traffic. - Port 4001 is Caplin's libp2p TCP listen address, not DISCV5. The flag's own help text says DISCV5, which is a misnomer: discv5 is UDP-only and runs on 4000, while 4001 feeds multiAddressBuilder for peering. - torrent.log is at <datadir>/logs/torrent.log, built from the datadir, and does not follow --log.dir.path.
Mirrors 927ef96 on the release/3.6 half. @yperbasis raised both against #23674; main has them identically, verified here rather than assumed. main's generator strips <TabItem> along with every other component, so the five per-network disk tables land in llms-full.txt one after another with nothing saying which network each describes. Ported #22919's label-to-heading promotion and its TabItemLabelTests class -- only that part, since main's generator also carries #23335's landing-card work. 39 tests pass and the regenerated bundle now labels all five tables. The provenance sentence claimed every figure came from Erigon + Caplin "with the sole exception of the --prune.mode flag", which main's own Sepolia, Hoodi and Chiado captions contradict -- they say execution layer only. Restored #22919's reviewed wording: "varying only the --prune.mode flag unless a tab notes otherwise".
#22919 landed on `release/3.5` and was never forward-ported. When `docs-deploy` switched to `release/3.6` on 2026-08-25, the published site silently lost all of it. This brings it onto `release/3.6`, re-derived against this branch's source rather than copied from 3.5. Three things the site currently gets wrong: - The Overview table recommends **RAID 0** and floats **ZFS** for archive nodes, which the restored Filesystem section directly contradicts. Its Disk Type and CPU rows are also missing two line breaks (`Avoid HDDs.SSD performance`, `Full nodes8–16 cores`). - The Hetzner note calls the firewall **stateless for both product lines**. Cloud is stateful, and adding outbound rules there flips outbound to implicit deny — which breaks the snapshot download. - That note's port table lists **9000 for Caplin**. That is Lighthouse's default; Caplin's own are `4000` UDP and `4001` TCP (`caplin.discovery.port`, `caplin.discovery.tcpport`). The downloader's `42069` was missing entirely. Hardware Requirements regains the Filesystem section (ext4/XFS, `noatime`, why latency is the bottleneck, why ZFS and Btrfs are the wrong shape here) and Sync Times. Troubleshooting regains the reserved-IPv4 list worth blocking so outbound dials do not trip Hetzner's abuse detection, and `SIGQUIT` for a wedged node (Erigon installs no `SIGQUIT` handler, so it falls through to the Go runtime's all-goroutine dump). Also: the `ERIGON_` env-var prefix rule (Erigon accepts both spellings, warns on the bare one, and the Docker variables do not take it), the `torrent.log` verbosity rule, the Beacon API's ~6 GB RAM cost, `make DIST=… install`, and what `--batchSize` does to MDBX growth. Separately, `--rpc.subscription.filters.maxtopics` counts alternatives **across all positions**, not per position — `topicCount` is a single counter spanning the outer loop in `rpc/rpchelper/filters.go` on this branch. The flag's `Usage` string here does not say so; `main`'s prose does, so this takes that wording. The `rpcdaemon --help` paste is left alone: it must keep matching this branch's actual output. Dual-commit pair with #23675 (`main`). Gate: `npm ci && npm run build` green, `generate-llms.py --check` OK (73 pages), `render-disk-sizes.py --check` OK, editorial scan and `sidebar_position` lint clean. --------- Co-authored-by: Bloxster <gianni.morselli@erigon.tech>
…rigontech#23595, erigontech#23625 to main (erigontech#23676) Ports five docs PRs merged to `release/3.6` between 2026-08-20 and 08-28. Every claim was re-derived against `main`'s own source rather than copied across — three did not survive that check, and two needed adapting. | Ported | Brings | | --- | --- | | erigontech#23359 | The state-cache environment variables | | erigontech#23587 | Caplin block production since v3.6, and the disk-storage claim in the Caplin intro | | erigontech#23593 | Pruning Modes: receipt-cache stickiness, `keep-all`, snapshot reclaim | | erigontech#23595 | `eth.md` JSON-RPC deviations and `trace.md` withdrawals / `gasBailOut` | | erigontech#23625 | The `--externalcl` correction and the Layer 2 page description | ### Written differently here, because release/3.6 is wrong for main - **`eth_getFilterLogs` no longer resets a filter's eviction deadline.** erigontech#23296 rewrote it to read the stored criteria and serve them through the `eth_getLogs` path, dropping the `TouchSubscription` call `release/3.6` still makes. A client polling only with `eth_getFilterLogs` loses its filter after five idle minutes. This documents it as it is, but it reads like an unintended side effect of erigontech#23296 rather than a deliberate change. - **`BlockNumberOrHash.UnmarshalJSON` has a top-level `"latestExecuted"` case on `main`**, so the bare string works on `eth_call` and friends. On `release/3.6` only the object-wrapped form does. - **`eth_fillTransaction` rejects three inputs on `main`** that `release/3.6` accepts: `gasPrice` with `authorizationList`, an empty `authorizationList`, and a derived `maxFeePerGas` or `maxFeePerBlobGas` that overflows 256 bits. - **The state caches do not start at a flat 1024 entries.** Start is `max(1024, shards × 16)` bounded by the ceiling, with the shard count following `min(ceiling/64, GOMAXPROCS × 16)` rounded to powers of two. `minShardStart` does not exist on `release/3.6` at all. ### Adapted for the Polygon removal (erigontech#23497) The `gasBailOut` burn-contract note drops the Bor chains, and the replay-path note drops Bor state-sync transactions. ### Verified unchanged, then ported as written `eth_getWitness` / `eth_getTxWitness` including the genesis and empty-access-set early returns; the withdrawals `stateDiff` shapes; Caplin payload preparation, head publication and default graffiti (`payload_preparation.go` is byte-identical across the branches); the `--prune.include-receipts` stickiness warning; and the `STATE_CACHE_*` defaults, whose "new in v3.6" comparisons check out against `release/3.5`. The llms.txt cross-link on `why-using-erigon` is deliberately left out — it belongs to erigontech#23336. Follows erigontech#23675. Gate: `npm ci && npm run build` green, `generate-llms.py --check` OK (72 pages), `render-disk-sizes.py --check` OK, editorial scan and `sidebar_position` lint clean. --------- Co-authored-by: Bloxster <gianni.morselli@erigon.tech>
Resolves against the tab work that landed on main in #23675. That change teaches strip_mdx() to promote <TabItem label=...> to a heading, so the disk-size tables stop reading as five unlabelled tables in a row. This branch deletes strip_mdx() entirely and takes page text from the built site instead, where the tablist markup already carries the binding, so the patch applies to code that is no longer here. Resolved to this branch's reader, which labels every one of those tables — as bold rather than as a heading, which is the one behaviour change this merge carries. Artifacts regenerated from a full build rather than hand-merged.
#22919 landed this material on
release/3.5and was never forward-ported. #23674 puts it onrelease/3.6; this is themainhalf. Every claim was re-derived againstmain's source rather than copied across.Corrections to guidance that is currently wrong
RAID 0 for multiple disks (Speed)and suggests ZFS for archive nodes. Both are replaced, and the new Filesystem section explains why.9000for Caplin. That is Lighthouse's default; Caplin's own are4000UDP and4001TCP (caplin.discovery.port,caplin.discovery.tcpport). The downloader's42069was missing entirely.Avoid HDDs.SSD performance,Full nodes8–16 cores).New sections
Filesystem — ext4/XFS,
noatime, why disk latency rather than throughput is the bottleneck, and why ZFS and Btrfs are the wrong shape for a memory-mapped B-tree.This section is new guidance from #22919, not migrated README text — the README never carried it. It is here for two reasons: the corrected Overview rows above are bare assertions without it, and #23524 added a startup check that warns per filesystem type and links readers to this page, which today says nothing about filesystems.
Sync Times, and the reserved-IPv4 list worth blocking so outbound dials do not trip Hetzner's abuse detection.
Smaller additions
SIGQUITfor a wedged node; theERIGON_env-var prefix rule; thetorrent.logverbosity rule; the Beacon API's ~6 GB RAM cost;make DIST=… installfor running outside the build tree; and what--batchSizedoes to MDBX growth.Per a992b2c the Cloud Storage Considerations section in
multiple-instances.mdis dropped here rather than updated — a net removal, since the section exists onmaintoday. #23674 keeps and updates it onrelease/3.6, so the pair diverges on this one section; whether 3.6 should take the same cut is a maintainer call, not assumed here.Dual-commit pair with #23674 (
release/3.6), which is the half that reaches readers today. Stacks alongside #23676.Gate:
npm ci && npm run buildgreen,generate-llms.py --checkOK (72 pages),render-disk-sizes.py --checkOK, editorial scan andsidebar_positionlint clean.