Documentation
¶
Index ¶
- Constants
- Variables
- func AddCustomRPC(cfg *config.Config, chainID int, chainName, endpoint string, readOnly bool) error
- func AddPublicRPCs(cfg *config.Config, chainID int, chainName string, endpoints []RPCEndpoint, ...) error
- func Ago(d time.Duration) string
- func CheckNetworkDiskSpace(u *ui.UI, dataDir, network, mode, executionClient string, scope ArchiveScope) error
- func DefaultChainListFetcher() ([]byte, error)
- func Delete(cfg *config.Config, u *ui.UI, deploymentIdentifier string) error
- func DeregisterERPCUpstream(cfg *config.Config, networkType, id string) error
- func FormatArchiveScope(network, mode, since, pruneKind string, pruneBlock, pruneDistance uint64) string
- func FormatBytes(n uint64) string
- func GrafanaNodeURL(namespace string) string
- func Install(cfg *config.Config, u *ui.UI, network string, overrides map[string]string, ...) error
- func List(cfg *config.Config, u *ui.UI) error
- func ListDeployments(cfg *config.Config) []string
- func ListInstanceIDs(cfg *config.Config) ([]string, error)
- func LocalUpstreamID(networkType, id string) string
- func ProbeBeaconAPI(ctx context.Context, client *http.Client, base string, cl *ConsensusStatus)
- func ProbeExecutionAPI(ctx context.Context, client *http.Client, base string, el *ExecutionStatus)
- func ReconcileERPCOverlay(cfg *config.Config, u *ui.UI)
- func ReconcileRecordedRPCs(cfg *config.Config, u *ui.UI)
- func RegisterERPCUpstream(cfg *config.Config, networkType, id string) error
- func RemovePublicRPCs(cfg *config.Config, chainID int) error
- func ResetERPC(cfg *config.Config, u *ui.UI) error
- func ResolveChainID(nameOrID string) (int, string, error)
- func ResolveInstance(cfg *config.Config, args []string) (identifier string, remaining []string, err error)
- func ResumeInstalled(cfg *config.Config, u *ui.UI) error
- func SetERPC(cfg *config.Config, u *ui.UI, path string) error
- func SortByQuality(endpoints []RPCEndpoint)
- func Start(cfg *config.Config, u *ui.UI, identifier string) error
- func Stop(cfg *config.Config, u *ui.UI, identifier string) error
- func Sync(cfg *config.Config, u *ui.UI, deploymentIdentifier string) error
- func SyncAll(cfg *config.Config, u *ui.UI) error
- func VerdictUnhealthy(state string) bool
- type ArchiveScope
- type ChainEntry
- type ChainListFetcher
- type ConsensusStatus
- type Deployment
- type ERPCAttempt
- type ERPCChain
- type ERPCChainCount
- type ERPCOverlay
- type ERPCOverlayStatus
- type ERPCPod
- type ERPCStatus
- type ERPCUpstream
- type ExecutionStatus
- type Hardfork
- type NodeERPC
- type NodeProber
- func (p *NodeProber) Close()
- func (p *NodeProber) Gather(ctx context.Context, deployments []Deployment, opts StatusOptions) StatusReport
- func (p *NodeProber) Probe(ctx context.Context, d Deployment) NodeStatus
- func (p *NodeProber) ProbeAll(ctx context.Context, deployments []Deployment) []NodeStatus
- func (p *NodeProber) StartSession(ctx context.Context)
- type NodeStatus
- type PodProblem
- type PodStatus
- type RPCEndpoint
- type RPCNetworkInfo
- type RPCUpstreamInfo
- type RateTracker
- type RecordedChain
- type RecordedChainlist
- type RecordedCustom
- type RecordedRPCs
- type StatusOptions
- type StatusReport
- type StorageStatus
- type SyncStage
- type TemplateField
- type Termination
- type Verdict
Constants ¶
const ( ERPCHealthy = "healthy" ERPCDegraded = "degraded" ERPCDown = "down" ERPCUnknown = "unknown" )
eRPC health states.
const ( VerdictSynced = "synced" VerdictSyncing = "syncing" VerdictWaiting = "waiting" VerdictStopped = "stopped" VerdictDegraded = "degraded" VerdictELOffline = "el_offline" VerdictUnreachable = "unreachable" VerdictNotDeployed = "not_deployed" VerdictNotProbed = "not_probed" VerdictNotSupported = "not_supported" )
Verdict states, from best to worst. JSON consumers key on these.
const ( ERPCSyncInSync = "in-sync" ERPCSyncDrifted = "drifted" ERPCSyncNotApplied = "not-applied" )
ERPCSyncInSync / ERPCSyncDrifted / ERPCSyncNotApplied are the ClusterSync values StatusERPC can report; "" means the cluster couldn't be checked.
const ( ProblemRestarting = "restarting" ProblemRestarted = "restarted" ProblemPending = "pending" ProblemImagePull = "image_pull" ProblemStarting = "starting" ProblemFailed = "failed" )
Pod problem states.
const ( StageDone = "done" StageCurrent = "current" StagePending = "pending" StageStalled = "stalled" )
Stage states.
const ( UnitBlocks = "blocks" UnitSlots = "slots" )
Units of SyncStage.Block/Target.
const ( // ERPCEndpoint is the host-side eRPC route (hostname-restricted to // obol.stack); append /<network> (the chain alias). ERPCEndpoint = "http://obol.stack:8080/rpc" )
const TypeEthereum = "ethereum"
TypeEthereum is the network type (and embedded network directory) of a local Ethereum node deployment, e.g. the "ethereum" in "ethereum/mainnet".
Variables ¶
var MainnetHardforks = []Hardfork{
{
Name: "merge",
DisplayName: "the merge",
Block: 15537394,
Date: "2022-09-15",
ApproxArchiveSizeTB: 1.5,
},
{
Name: "shanghai",
DisplayName: "shanghai",
Block: 17034870,
Date: "2023-04-12",
ApproxArchiveSizeTB: 1.2,
},
{
Name: "cancun",
DisplayName: "cancun",
Block: 19426587,
Date: "2024-03-13",
ApproxArchiveSizeTB: 0.8,
},
{
Name: "prague",
DisplayName: "prague",
Block: 22431084,
Date: "2025-05-07",
ApproxArchiveSizeTB: 0.4,
},
{
Name: "osaka",
DisplayName: "osaka",
Block: 23935694,
Date: "2025-12-03",
ApproxArchiveSizeTB: 0.2,
},
}
MainnetHardforks is the ordered list of mainnet hardforks supported by --since presets, oldest first.
Functions ¶
func AddCustomRPC ¶ added in v0.5.0
AddCustomRPC adds a single custom RPC endpoint for a chain to the eRPC ConfigMap. Uses the "custom-" prefix to distinguish from ChainList-sourced upstreams. When readOnly is true, eth_sendRawTransaction and eth_sendTransaction are blocked.
func AddPublicRPCs ¶ added in v0.5.0
func AddPublicRPCs(cfg *config.Config, chainID int, chainName string, endpoints []RPCEndpoint, readOnly bool) error
AddPublicRPCs adds ChainList RPCs for a chain to the eRPC ConfigMap. When readOnly is true, eth_sendRawTransaction and eth_sendTransaction are blocked.
func CheckNetworkDiskSpace ¶ added in v0.10.0
func CheckNetworkDiskSpace(u *ui.UI, dataDir, network, mode, executionClient string, scope ArchiveScope) error
CheckNetworkDiskSpace warns when the data directory has less free disk than the install is expected to need. The default answer is to continue: in non-interactive contexts (no TTY, JSON mode) the prompt auto-accepts so scripted installs don't deadlock. The user only blocks the install by explicitly declining at an interactive prompt.
func DefaultChainListFetcher ¶ added in v0.5.0
DefaultChainListFetcher fetches from the real ChainList API.
func DeregisterERPCUpstream ¶ added in v0.3.2
DeregisterERPCUpstream removes a previously registered local upstream from the eRPC ConfigMap.
func FormatArchiveScope ¶ added in v0.17.0
func FormatArchiveScope(network, mode, since, pruneKind string, pruneBlock, pruneDistance uint64) string
FormatArchiveScope renders an ethereum node's mode and history scope for humans, so a partial archive is not mistaken for a genesis archive:
full archive (genesis / no pruning) archive since cancun (block 19,426,587) archive since block 22,500,000 archive, last 365d archive, last 2,628,000 blocks (~365d) (no since recorded)
Nodes installed before `since` was recorded have it empty; a pruneBlock matching a known mainnet hardfork is then named via HardforkByBlock.
func FormatBytes ¶ added in v0.17.0
FormatBytes renders bytes as "412 GiB" / "1.1 TiB".
func GrafanaNodeURL ¶ added in v0.17.0
GrafanaNodeURL is the obol-eth-node dashboard filtered to one namespace.
func Install ¶
func Install(cfg *config.Config, u *ui.UI, network string, overrides map[string]string, force bool) error
Install creates a network configuration by executing Go templates and saving to config directory
func ListDeployments ¶ added in v0.15.0
ListDeployments returns every installed local network deployment as "<network>/<id>", sorted.
func ListInstanceIDs ¶ added in v0.5.0
ListInstanceIDs returns all installed network deployment identifiers (as "network/id" strings) by walking the networks directory on disk.
func LocalUpstreamID ¶ added in v0.17.0
LocalUpstreamID is the eRPC upstream id RegisterERPCUpstream uses for a local deployment.
func ProbeBeaconAPI ¶ added in v0.16.0
ProbeBeaconAPI fills cl from the beacon node API at base. /node/syncing is the reachability gate; peer count, version and (for Lighthouse) its own sync state are best-effort.
func ProbeExecutionAPI ¶ added in v0.16.0
ProbeExecutionAPI fills el from the EL JSON-RPC at base. eth_syncing is the reachability gate; the other calls are best-effort.
func ReconcileERPCOverlay ¶ added in v0.14.0
ReconcileERPCOverlay re-applies the host-side overlay into the live eRPC ConfigMap. Called after ReconcileRecordedRPCs on stack up. Best-effort: missing overlay is a silent no-op; apply errors are warned, not fatal.
func ReconcileRecordedRPCs ¶ added in v0.10.0
ReconcileRecordedRPCs replays recorded remote upstreams into a (possibly fresh) cluster. Called after `obol stack up`. Best-effort per chain.
func RegisterERPCUpstream ¶ added in v0.3.2
RegisterERPCUpstream reads the deployed network's RPC endpoint and adds it as an upstream in the eRPC ConfigMap. The local node becomes the primary upstream (group: "primary") with automatic fallback to existing remote upstreams.
func RemovePublicRPCs ¶ added in v0.5.0
RemovePublicRPCs removes all ChainList RPCs for a chain from the eRPC ConfigMap.
func ResetERPC ¶ added in v0.14.0
ResetERPC removes overlay-owned fragments from the live ConfigMap, then deletes the host-side overlay and provenance files. If cluster cleanup fails, the files are deliberately retained so reset or stack-up reconciliation can retry without losing ownership information.
func ResolveChainID ¶ added in v0.5.0
ResolveChainID converts a chain name or numeric string to a chain ID. Returns the chain ID and the resolved name (for display).
func ResolveInstance ¶ added in v0.5.0
func ResolveInstance(cfg *config.Config, args []string) (identifier string, remaining []string, err error)
ResolveInstance determines which network deployment to target based on how many deployments are installed:
- 0 deployments: returns an error prompting the user to install one
- 1 deployment: auto-selects it, returns args unchanged
- 2+ deployments: expects args[0] to be a known "network/id" identifier; consumes it from args and returns the rest. Errors if no match.
func ResumeInstalled ¶ added in v0.15.0
ResumeInstalled re-deploys installed local networks whose helm releases are missing (fresh / recreated cluster) or not in "deployed" state. Healthy deployments skip the costly per-network `helmfile sync`, but ethereum ones are re-registered with eRPC: `obol stack up` re-renders the eRPC ConfigMap without local upstreams (they aren't recorded), so without this a healthy node silently drops out of /rpc after the next eRPC restart. Registration merges by id and only rolls eRPC when the config changed. `obol network sync --all` remains the explicit "force re-sync everything" path. Deployments recorded as stopped (`obol network stop`) are skipped.
Best-effort per deployment; failures warn and are joined into the result.
func SetERPC ¶ added in v0.14.0
SetERPC loads an overlay YAML from path, persists it under ConfigDir as the complete desired operator overlay, and reconciles the live eRPC ConfigMap to it. Entries owned by the previous overlay but omitted from the new document are removed (or restored from provenance) before the new entries are merged.
func SortByQuality ¶ added in v0.5.0
func SortByQuality(endpoints []RPCEndpoint)
SortByQuality sorts RPC endpoints by tracking quality. Preference: tracking=none > tracking=limited > tracking=unknown > anything else.
func Start ¶ added in v0.17.0
Start undoes Stop: clears `stopped`, scales the workloads back to 1 (or runs a full sync when the cluster no longer has them, e.g. after it was recreated) and registers the node with eRPC again.
func Stop ¶ added in v0.17.0
Stop scales a deployment's node workloads to 0, keeping its PVCs, takes its local upstream out of eRPC (traffic falls back to remote RPCs) and records `stopped: true` in its values.yaml so `network sync` and `stack up` keep it down. With the cluster down only the record is written; it applies on the next `obol stack up`.
func SyncAll ¶ added in v0.3.2
SyncAll syncs all installed network deployments found in the config directory.
func VerdictUnhealthy ¶ added in v0.17.0
VerdictUnhealthy reports whether a verdict state means the node needs attention (`network status` exits 3 for these). A deliberately stopped node, or one that is still syncing, is not unhealthy.
Types ¶
type ArchiveScope ¶ added in v0.10.0
type ArchiveScope struct {
// Kind is one of: "all" (full archive from genesis), "before" (prune
// before a specific block), "distance" (keep last N blocks of history).
Kind string
// Block is set when Kind == "before".
Block uint64
// Distance is set when Kind == "distance".
Distance uint64
// Label is a human-readable description for logs/picker confirmation.
Label string
// Since is the canonical human token for the scope (a hardfork name
// like "cancun", a duration like "365d", a raw block number, or
// "genesis"). Written back to values.yaml so `network list|status` can
// show what the user chose rather than only the resolved block.
Since string
}
ArchiveScope is the resolved meaning of --since after parsing.
func ParseSince ¶ added in v0.10.0
func ParseSince(raw string) (ArchiveScope, error)
ParseSince resolves a --since value into an ArchiveScope. Accepted forms:
- "genesis", "all": full archive from genesis
- "merge", "shanghai", "cancun", "prague", "osaka": EL hardfork name
- "<N>d", "<N>mo", "<N>y": duration back from chain head (12s slots)
- "<block>": raw block number (any unsigned integer)
Mode is reth-anchored: "before" presets get translated to reth's --prune.<segment>.before flags; "distance" presets to --prune.<segment>.distance.
type ChainEntry ¶ added in v0.5.0
type ChainEntry struct {
Name string `json:"name"`
Chain string `json:"chain"`
ChainID int `json:"chainId"`
RPC []any `json:"rpc"` // mix of strings and objects
}
ChainEntry represents a single chain entry from the ChainList API.
type ChainListFetcher ¶ added in v0.5.0
ChainListFetcher abstracts the HTTP fetch so tests can inject fixtures.
type ConsensusStatus ¶ added in v0.16.0
type ConsensusStatus struct {
Reachable bool `json:"reachable"`
Error string `json:"error,omitempty"`
Version string `json:"version,omitempty"`
HeadSlot uint64 `json:"head_slot"`
SyncDistance uint64 `json:"sync_distance"`
IsSyncing bool `json:"is_syncing"`
IsOptimistic bool `json:"is_optimistic"`
ELOffline bool `json:"el_offline"`
Peers *uint64 `json:"peers,omitempty"`
// SyncState is Lighthouse's own sync state (/lighthouse/syncing):
// SyncingFinalized, SyncingHead, BackFillSyncing, SyncTransition,
// Synced or Stalled. Empty for other clients.
SyncState string `json:"sync_state,omitempty"`
SyncTargetSlot uint64 `json:"sync_target_slot,omitempty"`
BackfillCompleted uint64 `json:"backfill_completed,omitempty"`
BackfillRemaining uint64 `json:"backfill_remaining,omitempty"`
// Stages is the human view of the sync (finalized → head → backfill).
Stages []SyncStage `json:"stages,omitempty"`
}
ConsensusStatus is what the beacon node API says about itself.
type Deployment ¶ added in v0.16.0
type Deployment struct {
Type string `json:"type"`
ID string `json:"id"`
Namespace string `json:"namespace"`
Network string `json:"network,omitempty"`
ExecutionClient string `json:"execution_client,omitempty"`
ConsensusClient string `json:"consensus_client,omitempty"`
Mode string `json:"mode,omitempty"`
// ArchiveScope is the human-readable mode + history scope, e.g. "full",
// "archive", "archive since cancun (block 19,426,587)" or
// "archive, last 365d" (ethereum only; see FormatArchiveScope).
ArchiveScope string `json:"archive_scope,omitempty"`
// Raw pruning scope from values.yaml (ethereum only).
PruneKind string `json:"prune_kind,omitempty"`
PruneBlock uint64 `json:"prune_block,omitempty"`
PruneDistance uint64 `json:"prune_distance,omitempty"`
Since string `json:"since,omitempty"`
// Stopped is set by `obol network stop`: workloads scaled to 0, data
// kept, not registered with eRPC (values.yaml `stopped: true`).
Stopped bool `json:"stopped,omitempty"`
// Error is set when values.yaml could not be read; the deployment
// directory still exists, so it is listed rather than hidden.
Error string `json:"error,omitempty"`
}
Deployment is one installed local node, read from its values.yaml under $CONFIG_DIR/networks/<type>/<id>/. Fields that a network type does not have (e.g. clients for aztec) stay empty.
func InstalledDeployments ¶ added in v0.16.0
func InstalledDeployments(cfg *config.Config) []Deployment
InstalledDeployments returns every installed network deployment (see ListDeployments) with the settings from its values.yaml. It only reads the config dir, so it works with the cluster down. Never returns nil.
func (Deployment) Identifier ¶ added in v0.16.0
func (d Deployment) Identifier() string
Identifier is the "<type>/<id>" form every network subcommand accepts.
type ERPCAttempt ¶ added in v0.17.0
type ERPCAttempt struct {
Upstream string `json:"upstream"`
Phase string `json:"phase,omitempty"`
Result string `json:"result,omitempty"`
Won bool `json:"won,omitempty"`
}
ERPCAttempt is one upstream eRPC tried for the probe request, from its X-Erpc-Upstreams header ("local-ethereum-mainnet=primary:empty").
func ParseERPCUpstreamsHeader ¶ added in v0.17.0
func ParseERPCUpstreamsHeader(h string) []ERPCAttempt
ParseERPCUpstreamsHeader parses eRPC's X-Erpc-Upstreams header: "local-ethereum-mainnet=primary:empty;obol-rpc-mainnet=sweep:success:won".
type ERPCChain ¶ added in v0.17.0
type ERPCChain struct {
Network string `json:"network"`
ChainID int `json:"chain_id"`
Upstreams []ERPCUpstream `json:"upstreams"`
// Serving is the upstream that answered one eth_blockNumber sent
// through eRPC ("" when not probed or nobody answered).
Serving string `json:"serving,omitempty"`
FromCache bool `json:"from_cache,omitempty"`
Attempts []ERPCAttempt `json:"attempts,omitempty"`
ProbeError string `json:"probe_error,omitempty"`
}
ERPCChain is one chain eRPC routes, keyed by the same short network name as `obol network list` (the eRPC alias, else chain-<id>).
func ERPCChainsFromConfig ¶ added in v0.17.0
func ERPCChainsFromConfig(erpcConfig map[string]any, installed []Deployment) (string, []ERPCChain)
ERPCChainsFromConfig lists the chains in an eRPC config with their upstreams in priority order, sorted by chain id, and returns the project id that prefixes request paths. Upstreams named local-<type>-<id> are linked to the matching installed deployment.
type ERPCChainCount ¶ added in v0.17.0
type ERPCChainCount struct {
ChainID int `json:"chain_id"`
Name string `json:"name"`
Upstreams int `json:"upstreams"`
}
ERPCChainCount is the v0.16 per-chain upstream count (kept for JSON consumers; Chains has the detail).
type ERPCOverlay ¶ added in v0.14.0
type ERPCOverlay struct {
Version int `yaml:"version"`
// Networks are merged into projects[0].networks by chainId (preferred)
// or alias. Matching entries are replaced; others are appended.
Networks []map[string]any `yaml:"networks,omitempty"`
// Upstreams are merged into projects[0].upstreams by id. Matching
// entries are replaced; others are appended (after existing).
Upstreams []map[string]any `yaml:"upstreams,omitempty"`
// RateLimiters budgets are merged by id; other top-level keys are
// shallow-replaced (see mergeRateLimiters).
RateLimiters map[string]any `yaml:"rateLimiters,omitempty"`
// CachePoliciesAdd are appended to database.evmJsonRpcCache.policies
// when no existing policy has the same network+method+finality triple.
CachePoliciesAdd []map[string]any `yaml:"cachePoliciesAdd,omitempty"`
}
ERPCOverlay is the durable operator overlay document. Fragments are free-form maps so operators can pass full eRPC YAML objects (scoreMultipliers, failsafe, rateLimitBudget, …) without a rigid schema.
type ERPCOverlayStatus ¶ added in v0.14.0
type ERPCOverlayStatus struct {
Path string
Present bool
Version int
NetworkCount int
UpstreamCount int
BudgetCount int
CachePolicyAdd int
NetworkKeys []string
UpstreamIDs []string
ContentHash string
// ClusterSync is a best-effort comparison of ContentHash against the
// live ConfigMap's erpcOverlayAnnotKey annotation:
// "in-sync" | "drifted" | "not-applied" | "" (cluster unreachable/unknown).
ClusterSync string
}
ERPCOverlayStatus is a read-only summary for CLI status.
func StatusERPC ¶ added in v0.14.0
func StatusERPC(cfg *config.Config) (*ERPCOverlayStatus, error)
StatusERPCOverlay returns a summary of the on-disk overlay (no cluster I/O).
type ERPCPod ¶ added in v0.17.0
type ERPCPod struct {
Name string `json:"name"`
Phase string `json:"phase"`
Ready bool `json:"ready"`
Restarts int `json:"restarts"`
Reason string `json:"reason,omitempty"`
}
ERPCPod is an eRPC gateway pod.
type ERPCStatus ¶ added in v0.17.0
type ERPCStatus struct {
Endpoint string `json:"endpoint"`
Health string `json:"health"`
Pods []ERPCPod `json:"pods"`
Upstreams []ERPCChainCount `json:"upstreams"`
Chains []ERPCChain `json:"chains"`
Error string `json:"error,omitempty"`
}
ERPCStatus is the RPC gateway's state.
type ERPCUpstream ¶ added in v0.17.0
type ERPCUpstream struct {
ID string `json:"id"`
// Local marks an upstream that is a local node deployment
// (local-<type>-<id>); Deployment is its "<type>/<id>".
Local bool `json:"local"`
Deployment string `json:"deployment,omitempty"`
}
ERPCUpstream is one configured upstream of a chain.
type ExecutionStatus ¶ added in v0.16.0
type ExecutionStatus struct {
Reachable bool `json:"reachable"`
Error string `json:"error,omitempty"`
ClientVersion string `json:"client_version,omitempty"`
Syncing bool `json:"syncing"`
HeadBlock uint64 `json:"head_block"`
CurrentBlock uint64 `json:"current_block,omitempty"`
HighestBlock uint64 `json:"highest_block,omitempty"`
Peers *uint64 `json:"peers,omitempty"`
// Stages is reth's staged-sync pipeline from eth_syncing, in pipeline
// order, annotated with done/current/pending against the sync target.
Stages []SyncStage `json:"stages,omitempty"`
}
ExecutionStatus is what the EL's JSON-RPC says about itself.
type Hardfork ¶ added in v0.10.0
type Hardfork struct {
// Name is the canonical EL fork name used by --since=<name>.
Name string
// DisplayName is shown in the interactive picker.
DisplayName string
// Block is the first execution block at or after the fork activation.
Block uint64
// Date is the activation date, used only for picker labels.
Date string
// ApproxArchiveSizeTB is a rough estimate of mainnet archive disk usage
// when pruning state history before this block (reth). Used in picker
// labels so users have a realistic expectation. Values rounded.
ApproxArchiveSizeTB float64
}
Hardfork describes a mainnet hardfork activation point used by the partial-archive picker. All block numbers are verified for Ethereum mainnet — paris from the reth chainspec source, post-merge forks from the beacon API by computing slot = (fork_ts - beacon_genesis) / 12 and reading execution_payload.block_number from the canonical block at (or shortly after) that slot.
Verified 2026-05-27 against:
- reth v2.2.0 crates/chainspec/src/spec.rs (paris)
- go-ethereum params/config.go (post-merge fork timestamps)
- ethereum-beacon-api.publicnode.com (slot → execution block lookups)
func HardforkByBlock ¶ added in v0.17.0
HardforkByBlock returns the mainnet hardfork activating at exactly the given block, or nil. Used to name the scope of nodes installed before `since` was recorded in values.yaml.
func HardforkByName ¶ added in v0.10.0
HardforkByName returns the hardfork with the given name, or nil.
type NodeERPC ¶ added in v0.17.0
type NodeERPC struct {
// Upstream is the eRPC upstream id the node registers as.
Upstream string `json:"upstream"`
// Registered is whether the live eRPC config lists that upstream.
Registered bool `json:"registered"`
// Serving is the upstream that answered a probe request for the node's
// chain through eRPC (empty when not probed).
Serving string `json:"serving,omitempty"`
}
NodeERPC links a node to the RPC gateway.
type NodeProber ¶ added in v0.16.0
type NodeProber struct {
// Forward opens a tunnel to namespace/service:port and returns its base
// URL and a closer.
Forward func(ctx context.Context, namespace, service string, port int) (string, func(), error)
// Pods lists the pods in a namespace.
Pods func(ctx context.Context, namespace string) ([]PodStatus, error)
// ERPCConfig returns the parsed live eRPC config (erpc-config ConfigMap).
ERPCConfig func(ctx context.Context) (map[string]any, error)
// DiskUsage sums the bytes under dir (partial when it could not read
// everything in time). Nil disables the Data line.
DiskUsage func(ctx context.Context, dir string) (bytes uint64, partial bool, err error)
// FreeBytes reports free space on the filesystem holding path.
FreeBytes func(path string) (uint64, error)
// DataDir is the host directory holding PVC data (<ns>/<pvc>).
DataDir string
// HTTP is used for every API call; its Timeout bounds each request.
HTTP *http.Client
// Now is the clock for "last 3m ago" (defaults to time.Now).
Now func() time.Time
// contains filtered or unexported fields
}
NodeProber reaches in-cluster node APIs. Production wiring (NewKubectlNodeProber) uses `kubectl port-forward`s on obol's own kubeconfig; tests swap the funcs for httptest servers and fixtures.
By default every probe opens and closes its own forwards. After StartSession, forwards are kept open and reused across probes (for `network status --watch`) until Close; a forward whose API stopped answering is dropped and reopened on the next probe.
func NewKubectlNodeProber ¶ added in v0.16.0
func NewKubectlNodeProber(cfg *config.Config) *NodeProber
NewKubectlNodeProber returns a prober that reaches the cluster through obol's stack kubeconfig only (never the user's ambient KUBECONFIG).
func (*NodeProber) Close ¶ added in v0.17.0
func (p *NodeProber) Close()
Close closes every forward a session kept open. Safe without a session.
func (*NodeProber) Gather ¶ added in v0.17.0
func (p *NodeProber) Gather(ctx context.Context, deployments []Deployment, opts StatusOptions) StatusReport
Gather builds the whole status report: eRPC (pods, config, which upstream serves each chain right now) and every deployment, concurrently. It never fails; problems are reported inside the result.
func (*NodeProber) Probe ¶ added in v0.16.0
func (p *NodeProber) Probe(ctx context.Context, d Deployment) NodeStatus
Probe gathers pods + EL + CL status for one deployment and computes its verdict. Every failure degrades into the result; it never returns an error.
func (*NodeProber) ProbeAll ¶ added in v0.16.0
func (p *NodeProber) ProbeAll(ctx context.Context, deployments []Deployment) []NodeStatus
ProbeAll probes every deployment concurrently. Non-ethereum deployments are returned with VerdictNotSupported (no live probes for them yet).
func (*NodeProber) StartSession ¶ added in v0.17.0
func (p *NodeProber) StartSession(ctx context.Context)
StartSession keeps port-forwards open across probes until Close. ctx bounds the forwards' lifetime (cancel it, or call Close, to stop them).
type NodeStatus ¶ added in v0.16.0
type NodeStatus struct {
Deployment
Pods []PodStatus `json:"pods"`
PodsError string `json:"pods_error,omitempty"`
Problems []PodProblem `json:"problems"`
Execution *ExecutionStatus `json:"execution,omitempty"`
Consensus *ConsensusStatus `json:"consensus,omitempty"`
Storage *StorageStatus `json:"storage,omitempty"`
ERPC *NodeERPC `json:"erpc,omitempty"`
// GrafanaURL is the node's dashboard on the local Grafana route.
GrafanaURL string `json:"grafana_url,omitempty"`
Verdict Verdict `json:"verdict"`
}
NodeStatus is the live state of one installed deployment.
func Unprobed ¶ added in v0.17.0
func Unprobed(d Deployment, summary string) NodeStatus
Unprobed is the status of a deployment that is not probed live (--no-probe): stopped nodes still say so.
type PodProblem ¶ added in v0.17.0
type PodProblem struct {
Component string `json:"component"`
Pod string `json:"pod"`
State string `json:"state"`
Cause string `json:"cause,omitempty"`
Restarts int32 `json:"restarts,omitempty"`
LastAt *time.Time `json:"last_at,omitempty"`
Message string `json:"message"`
Hint string `json:"hint,omitempty"`
}
PodProblem is one pod-level issue, phrased once as state + cause + hint ("Restarting — OOMKilled 9× (last 3m ago)").
func PodProblems ¶ added in v0.17.0
func PodProblems(d Deployment, pods []PodStatus, now time.Time) []PodProblem
PodProblems turns pod state into problems, at most one per pod. Healthy pods (ready, no restart within the last hour) produce none.
func (PodProblem) Severe ¶ added in v0.17.0
func (p PodProblem) Severe() bool
Severe reports whether the problem stops the pod from serving (as opposed to a pod that is starting, or recovered from a recent restart).
type PodStatus ¶ added in v0.16.0
type PodStatus struct {
Name string `json:"name"`
Component string `json:"component"`
Phase string `json:"phase"`
Ready bool `json:"ready"`
Restarts int32 `json:"restarts"`
// Reason is the current waiting/terminated reason (CrashLoopBackOff,
// ContainerCreating, OOMKilled …).
Reason string `json:"reason,omitempty"`
// LastTermination is the most recent container exit (lastState), the
// cause behind a CrashLoopBackOff.
LastTermination *Termination `json:"last_termination,omitempty"`
// Unschedulable is the scheduler's message while the pod can't be
// placed (e.g. "0/1 nodes are available: 1 Insufficient memory.").
Unschedulable string `json:"unschedulable,omitempty"`
MemoryRequest string `json:"memory_request,omitempty"`
MemoryLimit string `json:"memory_limit,omitempty"`
}
PodStatus is a pod in the network namespace, condensed.
type RPCEndpoint ¶ added in v0.5.0
type RPCEndpoint struct {
URL string `json:"url"`
Tracking string `json:"tracking"` // "none", "limited", or "yes"
}
RPCEndpoint represents a single RPC endpoint from ChainList.
func FetchChainListRPCs ¶ added in v0.5.0
func FetchChainListRPCs(chainID int, fetcher ChainListFetcher) ([]RPCEndpoint, string, error)
FetchChainListRPCs fetches RPCs for a given chain ID from ChainList, filters for free/public HTTPS endpoints, and returns up to maxRPCs sorted by quality (tracking=none preferred over tracking=limited).
func FilterFreeRPCs ¶ added in v0.5.0
func FilterFreeRPCs(endpoints []RPCEndpoint) []RPCEndpoint
FilterFreeRPCs filters RPC endpoints to only include free, HTTPS, non-tracking endpoints.
func ParseAndFilterRPCs ¶ added in v0.5.0
func ParseAndFilterRPCs(data []byte, chainID, maxRPCs int) ([]RPCEndpoint, string, error)
ParseAndFilterRPCs parses ChainList JSON, finds the chain, filters and sorts RPCs. Exported for testing.
type RPCNetworkInfo ¶ added in v0.5.0
type RPCNetworkInfo struct {
ChainID int
Alias string
Upstreams []RPCUpstreamInfo
}
RPCNetworkInfo represents a network (chain) configured in eRPC.
func ListRPCNetworks ¶ added in v0.5.0
func ListRPCNetworks(cfg *config.Config) ([]RPCNetworkInfo, error)
ListRPCNetworks reads the eRPC ConfigMap and returns configured networks with their upstreams.
type RPCUpstreamInfo ¶ added in v0.5.0
RPCUpstreamInfo represents an upstream in the eRPC config for display.
type RateTracker ¶ added in v0.17.0
type RateTracker struct {
// Window is how far back samples count (default 10m).
Window time.Duration
// contains filtered or unexported fields
}
RateTracker turns successive status samples into per-stage rates and ETAs over a sliding window (network status --watch).
func NewRateTracker ¶ added in v0.17.0
func NewRateTracker() *RateTracker
NewRateTracker returns a tracker with a 10 minute window.
func (*RateTracker) Annotate ¶ added in v0.17.0
func (r *RateTracker) Annotate(nodes []NodeStatus, at time.Time)
Annotate records the current stage of each probed node and sets RatePerSec/ETASeconds on it once the window has two samples. The ETA accounts for a moving target (a beacon head advances 1 slot / 12s).
type RecordedChain ¶ added in v0.10.0
type RecordedChain struct {
Name string `yaml:"name"`
Chainlist *RecordedChainlist `yaml:"chainlist,omitempty"`
Custom *RecordedCustom `yaml:"custom,omitempty"`
}
RecordedChain holds the recorded upstream intent for one chain.
type RecordedChainlist ¶ added in v0.10.0
type RecordedChainlist struct {
ReadOnly bool `yaml:"readOnly"`
Endpoints []RPCEndpoint `yaml:"endpoints"`
}
RecordedChainlist snapshots the ChainList endpoints selected at add time, so replay is deterministic and offline (no re-fetch of chainlist.org).
type RecordedCustom ¶ added in v0.10.0
RecordedCustom is a `network add --endpoint` upstream.
type RecordedRPCs ¶ added in v0.10.0
type RecordedRPCs struct {
Version int `yaml:"version"`
Chains map[string]*RecordedChain `yaml:"chains"` // key: decimal chain ID
}
RecordedRPCs is the host-side record of operator-added remote upstreams.
type StatusOptions ¶ added in v0.17.0
type StatusOptions struct {
// NoProbe skips live API calls (node APIs and the eRPC serving probe);
// pods and the eRPC config are still read.
NoProbe bool
// Installed is every installed deployment, used to link eRPC's local
// upstreams to them. Defaults to the probed deployments.
Installed []Deployment
}
StatusOptions tunes Gather.
type StatusReport ¶ added in v0.17.0
type StatusReport struct {
Time time.Time `json:"time"`
ERPC ERPCStatus `json:"erpc"`
Nodes []NodeStatus `json:"nodes"`
}
StatusReport is `obol network status`: the gateway plus each node.
func (StatusReport) Unhealthy ¶ added in v0.17.0
func (r StatusReport) Unhealthy() []string
Unhealthy lists the nodes whose verdict needs attention.
type StorageStatus ¶ added in v0.17.0
type StorageStatus struct {
Path string `json:"path"`
ExecutionBytes uint64 `json:"execution_bytes"`
ConsensusBytes uint64 `json:"consensus_bytes"`
FreeBytes *uint64 `json:"free_bytes,omitempty"`
// Partial means some of it couldn't be read (permissions) or summed in
// time; the sizes are then lower bounds.
Partial bool `json:"partial,omitempty"`
}
StorageStatus is the on-disk size of a node's data (local-path PVCs live under <DataDir>/<namespace>/<pvc>) and the free space next to it.
func (*StorageStatus) TotalBytes ¶ added in v0.17.0
func (s *StorageStatus) TotalBytes() uint64
TotalBytes is execution + consensus data.
type SyncStage ¶ added in v0.17.0
type SyncStage struct {
Name string `json:"name"`
// Block is the progress reached (a block, a slot, or for backfill the
// number of slots filled), in Unit.
Block uint64 `json:"block"`
Target uint64 `json:"target,omitempty"`
State string `json:"state"`
Unit string `json:"unit,omitempty"`
// RatePerSec and ETASeconds are set by --watch once a few samples exist.
RatePerSec *float64 `json:"rate_per_sec,omitempty"`
ETASeconds *int64 `json:"eta_seconds,omitempty"`
}
SyncStage is one step of a client's sync: a reth pipeline stage, or a beacon node phase (finalized sync, head sync, backfill).
type TemplateField ¶
type TemplateField struct {
Name string
DefaultValue string
FlagName string // CLI flag name derived from field name
Description string // Human-readable description from @description
EnumValues []string // Valid enum values from @enum
Required bool // Whether this field is required (no default value)
}
TemplateField represents a template field with its configuration
func ParseTemplateFields ¶
func ParseTemplateFields(networkName string) ([]TemplateField, error)
ParseTemplateFields extracts template fields from an embedded network values file Uses Go template parsing to identify field references and their annotations
type Termination ¶ added in v0.17.0
type Termination struct {
Reason string `json:"reason,omitempty"`
ExitCode int32 `json:"exit_code"`
FinishedAt time.Time `json:"finished_at,omitzero"`
}
Termination is one container exit.
type Verdict ¶ added in v0.16.0
type Verdict struct {
State string `json:"state"`
Summary string `json:"summary"`
ProgressPct *float64 `json:"progress_pct,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
Verdict is the one-line answer to "is my node usable yet?".
func ComputeVerdict ¶ added in v0.16.0
func ComputeVerdict(pods []PodStatus, el *ExecutionStatus, cl *ConsensusStatus) Verdict
ComputeVerdict turns raw node state into one state + one-line summary. The consensus view wins where both are available: it knows whether the EL is reachable over the engine API (el_offline) and whether the chain head is optimistic (EL still catching up). A client whose API is down because its pod is crash-looping makes the node degraded, even while the other client still reports progress.