Skip to content

Commit 61f0cbb

Browse files
author
bussyjd
committed
Merge remote-tracking branch 'origin/pr/559' into release/v0.10.0-rc7
2 parents be7e88b + a73c92a commit 61f0cbb

14 files changed

Lines changed: 835 additions & 20 deletions

File tree

CLAUDE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ obol sell delete ollama-gated -n llm
176176

177177
Two-stage templating: `values.yaml.gotmpl` with `@enum/@default/@description` annotations → CLI flags → rendered `values.yaml` (Stage 1), then `helmfile sync --state-values-file values.yaml --state-values-set id=<id>` (Stage 2). Unique namespaces: `<network>-<id>` where ID is petname or `--id <name>`. Local Ethereum nodes auto-registered as priority upstream in eRPC via `RegisterERPCUpstream()` (write methods blocked on local → routed to remote).
178178

179+
**Ethereum `--mode full|archive`** (default `full`): controls whether reth runs as a pruned full node (~500 GB mainnet / ~100 GB testnet) or an archive node retaining all historical state (~4 TB+ mainnet / ~300 GB testnet). Archive mode is for state replay (block explorers, historical `eth_call`, indexers); full mode is the right default for everything else. The mode flows through to (a) the reth `--full` arg in `internal/embed/networks/ethereum/helmfile.yaml.gotmpl`, (b) PVC sizing in `templates/pvc.yaml`, and (c) the `helmfile` `persistence.size` request. `obol network install ethereum` runs a disk-space preflight via `internal/network/preflight.go` — it warns when `cfg.DataDir` has less free disk than `(network, mode)` is expected to need, prompts the user, and auto-continues in non-interactive mode (no TTY / JSON output) so scripted installs don't deadlock. Other execution clients (geth, nethermind, besu, erigon) ignore the mode flag for now.
180+
181+
**Ethereum `--since` (partial archive)**: when `--mode=archive` would otherwise mean genesis-to-tip, `--since` bounds the archive at a known historical point and translates to reth's `--prune.account-history.{before,distance}` + `--prune.storage-history.{before,distance}` flags (plus `--prune.receipts.pre-merge` / `--prune.bodies.pre-merge` when the cutoff is at or before the merge). Accepted forms: EL hardfork names (`merge`, `shanghai`, `cancun`, `prague`, `osaka` — mainnet only, verified block numbers in `internal/network/hardforks.go`); durations (`365d`, `1y`, `6mo` — resolved against the post-merge 12s slot rate as a `--prune.*.distance` value); raw block numbers (`22500000`); or `genesis`/`all` (no extra args). Resolution happens in `resolveEthereumArchiveScope` in `internal/network/picker.go`: `--since` wins outright; if `--mode` is unset and a TTY is attached, a `full vs archive` picker runs; if `--mode=archive` is set without `--since` on a TTY, an `Archive scope` picker offers the hardfork presets + custom block + 365 days + genesis. Non-TTY defaults to `mode=full` (mode unset) or `since=genesis` (mode=archive). Resolved scope is appended to `values.yaml` as `pruneKind` / `pruneBlock` / `pruneDistance` and consumed by the helmfile. Partial archive is wired only for reth; geth/besu/erigon/nethermind emit a warning and run with chart defaults. Hardfork-name presets are rejected on testnets (mainnet block numbers don't apply).
182+
179183
## Stack Lifecycle
180184

181185
| Command | Action |

docs/getting-started.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,64 @@ obol network sync ethereum/demo
216216

217217
This creates the `ethereum-demo` namespace with an execution client (reth) and a consensus client (lighthouse).
218218

219+
### Full vs archive mode
220+
221+
`obol network install ethereum` defaults to `--mode=full`, which prunes
222+
historical state and needs ~500 GB on mainnet (~100 GB on testnets). Pass
223+
`--mode=archive` if you need to replay state across history (block
224+
explorers, historical `eth_call`, indexers); archive nodes hold the full
225+
state trie and grow to ~4 TB+ on mainnet.
226+
227+
```bash
228+
# Default: pruned full node
229+
obol network install ethereum --network=mainnet
230+
231+
# Archive node for state replay (requires ~4-5 TB free)
232+
obol network install ethereum --network=mainnet --mode=archive
233+
```
234+
235+
When `--mode` is omitted on a TTY, the installer prompts. The disk-space
236+
preflight warns when the data directory has less free disk than the
237+
chosen mode is likely to need.
238+
239+
### Partial archive (`--since`)
240+
241+
A full mainnet archive from genesis is ~4 TB+, but most archive use cases
242+
(indexers, recent-state replay) only need history back to a known point.
243+
`--since` keeps an archive bounded — reth gets the right `--prune.*`
244+
flags wired through the chart:
245+
246+
```bash
247+
# Archive back to the merge (Sep 2022, ~1.5 TB)
248+
obol network install ethereum --network=mainnet --mode=archive --since=merge
249+
250+
# Archive back to Cancun (Mar 2024, ~800 GB)
251+
obol network install ethereum --network=mainnet --mode=archive --since=cancun
252+
253+
# Archive of the last 365 days (~600 GB)
254+
obol network install ethereum --network=mainnet --mode=archive --since=365d
255+
256+
# Archive from a specific block forward
257+
obol network install ethereum --network=mainnet --mode=archive --since=22500000
258+
```
259+
260+
Accepted `--since` values:
261+
262+
| Form | Example | Meaning |
263+
|---|---|---|
264+
| EL fork name | `merge`, `shanghai`, `cancun`, `prague`, `osaka` | Prune state before that mainnet hardfork |
265+
| Duration | `365d`, `1y`, `6mo` | Keep last N blocks (~12s slot rate) |
266+
| Block number | `22500000` | Prune state before that block |
267+
| `genesis` / `all` | `genesis` | Full archive from genesis |
268+
269+
When `--mode=archive` is set without `--since` on a TTY, the installer
270+
shows an interactive picker. On non-TTY (scripts, CI), the default is
271+
`all history`. `--since` is currently fine-tuned for **reth**; other
272+
execution clients fall back to their chart-default behavior with a warning.
273+
274+
Fork-name presets reference mainnet block numbers — use a raw block
275+
number or a duration on testnets.
276+
219277
Verify:
220278

221279
```bash

internal/embed/infrastructure/values/erpc.yaml.gotmpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ config: |-
2929
- id: memory-cache
3030
driver: memory
3131
memory:
32-
maxItems: 10000
32+
# LRU cap on cached RPC responses. The connector is memory-only
33+
# (no disk), so the upper bound is enforced by the pod memory
34+
# limit below; this cap keeps cache RAM well under that limit.
35+
maxItems: 5000
3336
policies:
3437
- network: "*"
3538
method: "*"

internal/embed/infrastructure/values/monitoring.yaml.gotmpl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ prometheus:
1111
matchLabels:
1212
release: monitoring
1313
podMonitorNamespaceSelector: {}
14-
retention: 8d
14+
# Time-based retention is still honored, but retentionSize is the hard
15+
# cap that prevents the TSDB from filling the k3d node's writable layer
16+
# overnight and triggering DiskPressure → cascading pod evictions.
17+
# 2GB on emptyDir is plenty for a local single-node stack.
18+
retention: 2d
19+
retentionSize: 2GB
1520
resources:
1621
requests:
1722
cpu: 100m

internal/embed/networks/aztec/helmfile.yaml.gotmpl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ releases:
99
namespace: aztec-{{ .Values.id }}
1010
createNamespace: true
1111
chart: obol/aztec-node
12-
version: 0.2.0
12+
# renovate: datasource=helm depName=aztec-node registryUrl=https://obolnetwork.github.io/helm-charts
13+
version: 2.3.0
1314
values:
1415
- role: sequencer
1516
sequencer:
@@ -19,7 +20,8 @@ releases:
1920
networkName: '{{ .Values.id }}'
2021
image:
2122
repository: aztecprotocol/aztec
22-
tag: 2.1.5
23+
# renovate: datasource=docker depName=aztecprotocol/aztec
24+
tag: 4.3.0
2325
pullPolicy: Always
2426
node:
2527
replicas: 1

internal/embed/networks/ethereum/helmfile.yaml.gotmpl

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,20 @@ releases:
2424
namespace: ethereum-{{ .Values.id }}
2525
createNamespace: true
2626
chart: ethereum-helm-charts/ethereum-node
27+
# renovate: datasource=helm depName=ethereum-node registryUrl=https://ethpandaops.github.io/ethereum-helm-charts
28+
version: 0.2.14
2729
needs: [ethereum-pvcs]
2830
values:
2931
# Network and checkpoint sync configuration
32+
#
33+
# global.clientArgs.networks.<network>.execution.reth is the upstream
34+
# umbrella chart's per-network reth args list. We APPEND to it rather
35+
# than overriding reth.extraArgs directly, because reth.extraArgs in
36+
# the umbrella chart is a templated string that looks up this very
37+
# list — overriding it would silently drop the --chain=<testnet> arg
38+
# that testnets depend on. Mainnet's upstream list is empty; testnets
39+
# are ["--chain=<network>"]. We carry those over verbatim and add
40+
# --full only when mode != archive.
3041
- global:
3142
main:
3243
network: '{{ .Values.network }}'
@@ -36,46 +47,91 @@ releases:
3647
mainnet: https://mainnet-checkpoint-sync.attestant.io
3748
sepolia: https://checkpoint-sync.sepolia.ethpandaops.io
3849
hoodi: https://checkpoint-sync.hoodi.ethpandaops.io
50+
{{- if eq .Values.executionClient "reth" }}
51+
clientArgs:
52+
networks:
53+
{{ .Values.network }}:
54+
execution:
55+
reth:
56+
{{- if ne .Values.network "mainnet" }}
57+
- --chain={{ .Values.network }}
58+
{{- end }}
59+
{{- if ne .Values.mode "archive" }}
60+
- --full
61+
{{- else if eq (.Values.pruneKind | default "") "before" }}
62+
# Partial archive: prune state history before block N.
63+
# Receipts/bodies are pruned to the same cutoff via the
64+
# pre-merge presets where applicable; otherwise reth
65+
# uses the same `before` value.
66+
- --prune.account-history.before={{ .Values.pruneBlock }}
67+
- --prune.storage-history.before={{ .Values.pruneBlock }}
68+
{{- if le (int .Values.pruneBlock) 15537394 }}
69+
- --prune.receipts.pre-merge
70+
- --prune.bodies.pre-merge
71+
{{- else }}
72+
- --prune.receipts.before={{ .Values.pruneBlock }}
73+
- --prune.bodies.before={{ .Values.pruneBlock }}
74+
{{- end }}
75+
{{- else if eq (.Values.pruneKind | default "") "distance" }}
76+
# Partial archive: keep last N blocks of history.
77+
- --prune.account-history.distance={{ .Values.pruneDistance }}
78+
- --prune.storage-history.distance={{ .Values.pruneDistance }}
79+
{{- end }}
80+
{{- end }}
3981

40-
# Execution client (pinned versions — update periodically)
82+
# Execution client (pinned versions — Renovate-tracked)
83+
# Reth defaults to archive (~4TB+ mainnet). The --mode flag controls
84+
# whether we pass --full to prune historical state down to ~500GB,
85+
# wired through global.clientArgs above (NOT reth.extraArgs — see
86+
# comment above).
4187
- {{ .Values.executionClient }}:
4288
enabled: true
4389
image:
4490
{{- if eq .Values.executionClient "reth" }}
45-
tag: v1.11.1
91+
# renovate: datasource=github-releases depName=paradigmxyz/reth
92+
tag: v2.2.0
4693
{{- else if eq .Values.executionClient "geth" }}
47-
tag: v1.17.0
94+
# renovate: datasource=github-releases depName=ethereum/go-ethereum
95+
tag: v1.17.3
4896
{{- else if eq .Values.executionClient "nethermind" }}
49-
tag: "1.36.0"
97+
# renovate: datasource=github-releases depName=NethermindEth/nethermind
98+
tag: "1.37.2"
5099
{{- else if eq .Values.executionClient "besu" }}
51-
tag: "26.2.0"
100+
# renovate: datasource=github-releases depName=hyperledger/besu
101+
tag: "26.5.0"
52102
{{- else if eq .Values.executionClient "erigon" }}
53-
tag: v3.3.8
103+
# renovate: datasource=github-releases depName=erigontech/erigon
104+
tag: v3.4.2
54105
{{- end }}
55106
persistence:
56107
enabled: true
57-
size: 500Gi
108+
size: {{ if eq .Values.network "mainnet" }}{{ if eq .Values.mode "archive" }}4500Gi{{ else }}500Gi{{ end }}{{ else }}{{ if eq .Values.mode "archive" }}300Gi{{ else }}100Gi{{ end }}{{ end }}
58109
existingClaim: execution-{{ .Values.executionClient }}-{{ .Values.network }}
59110

60-
# Consensus client (pinned versions — update periodically)
111+
# Consensus client (pinned versions — Renovate-tracked)
61112
# The upstream chart wires --execution-endpoint and --network automatically.
62113
- {{ .Values.consensusClient }}:
63114
enabled: true
64115
image:
65116
{{- if eq .Values.consensusClient "lighthouse" }}
66-
tag: v8.1.1
117+
# renovate: datasource=github-releases depName=sigp/lighthouse
118+
tag: v8.1.3
67119
{{- else if eq .Values.consensusClient "prysm" }}
68-
tag: v7.1.2
120+
# renovate: datasource=github-releases depName=OffchainLabs/prysm
121+
tag: v7.1.4
69122
{{- else if eq .Values.consensusClient "teku" }}
70-
tag: "26.2.0"
123+
# renovate: datasource=github-releases depName=Consensys/teku
124+
tag: "26.4.0"
71125
{{- else if eq .Values.consensusClient "nimbus" }}
72-
tag: multiarch-v26.3.0
126+
# renovate: datasource=docker depName=statusim/nimbus-eth2
127+
tag: multiarch-v26.5.0
73128
{{- else if eq .Values.consensusClient "lodestar" }}
74-
tag: v1.40.0
129+
# renovate: datasource=github-releases depName=ChainSafe/lodestar
130+
tag: v1.43.0
75131
{{- end }}
76132
persistence:
77133
enabled: true
78-
size: 200Gi
134+
size: {{ if eq .Values.network "mainnet" }}{{ if eq .Values.mode "archive" }}500Gi{{ else }}200Gi{{ end }}{{ else }}{{ if eq .Values.mode "archive" }}100Gi{{ else }}50Gi{{ end }}{{ end }}
79135
existingClaim: consensus-{{ .Values.consensusClient }}-{{ .Values.network }}
80136

81137
# Metadata ConfigMap for frontend discovery

internal/embed/networks/ethereum/templates/pvc.yaml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,32 @@
11
{{- if eq .Release.Name "ethereum-pvcs" }}
2+
{{- /*
3+
PVC sizing is a function of (network, mode). Sizes are estimates with
4+
~30% headroom for chain growth. local-path storage does not pre-allocate,
5+
so these requests primarily document intent and serve as soft caps when
6+
a sized storage class is swapped in later.
7+
*/ -}}
8+
{{- $mode := default "full" .Values.mode -}}
9+
{{- $isArchive := eq $mode "archive" -}}
10+
{{- $execSize := "500Gi" -}}
11+
{{- $consensusSize := "200Gi" -}}
12+
{{- if eq .Values.network "mainnet" -}}
13+
{{- if $isArchive -}}
14+
{{- $execSize = "4500Gi" -}}
15+
{{- $consensusSize = "500Gi" -}}
16+
{{- else -}}
17+
{{- $execSize = "500Gi" -}}
18+
{{- $consensusSize = "200Gi" -}}
19+
{{- end -}}
20+
{{- else -}}
21+
{{- /* sepolia, hoodi and other testnets */ -}}
22+
{{- if $isArchive -}}
23+
{{- $execSize = "300Gi" -}}
24+
{{- $consensusSize = "100Gi" -}}
25+
{{- else -}}
26+
{{- $execSize = "100Gi" -}}
27+
{{- $consensusSize = "50Gi" -}}
28+
{{- end -}}
29+
{{- end -}}
230
---
331
# Ethereum Execution Client PVC
432
apiVersion: v1
@@ -12,7 +40,7 @@ spec:
1240
storageClassName: local-path
1341
resources:
1442
requests:
15-
storage: 500Gi
43+
storage: {{ $execSize }}
1644
---
1745
# Ethereum Consensus Client PVC
1846
apiVersion: v1
@@ -26,5 +54,5 @@ spec:
2654
storageClassName: local-path
2755
resources:
2856
requests:
29-
storage: 200Gi
57+
storage: {{ $consensusSize }}
3058
{{- end }}

internal/embed/networks/ethereum/values.yaml.gotmpl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,12 @@ executionClient: {{.ExecutionClient}}
1515
# @default lighthouse
1616
# @description Consensus layer client
1717
consensusClient: {{.ConsensusClient}}
18+
19+
# @enum full,archive
20+
# @default full
21+
# @description Node mode. 'full' prunes historical state (~500GB mainnet); 'archive' keeps all state for history replay (~4TB+ mainnet)
22+
mode: {{.Mode}}
23+
24+
# @default
25+
# @description Archive scope (only used with --mode=archive). Accepts: 'merge', 'shanghai', 'cancun', 'prague', 'osaka' (EL fork name); duration like '365d', '1y', '6mo'; raw block number; or 'genesis' for all history. Prompts interactively on TTY if omitted.
26+
since: {{.Since}}

0 commit comments

Comments
 (0)