Help us shape the future of Go! Take the 2026 Go Developer Survey

network

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2026 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ERPCHealthy  = "healthy"
	ERPCDegraded = "degraded"
	ERPCDown     = "down"
	ERPCUnknown  = "unknown"
)

eRPC health states.

View Source
const (
	PruneAll      = "all"
	PruneBefore   = "before"
	PruneDistance = "distance"
)

ArchiveScope kinds (and the pruneKind stored in a node's values.yaml).

View Source
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.

View Source
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.

View Source
const (
	ProblemRestarting = "restarting"
	ProblemRestarted  = "restarted"
	ProblemPending    = "pending"
	ProblemImagePull  = "image_pull"
	ProblemStarting   = "starting"
	ProblemFailed     = "failed"
)

Pod problem states.

View Source
const (
	StageDone    = "done"
	StageCurrent = "current"
	StagePending = "pending"
	StageStalled = "stalled"
)

Stage states.

View Source
const (
	UnitBlocks = "blocks"
	UnitSlots  = "slots"
)

Units of SyncStage.Block/Target.

View Source
const (

	// ERPCEndpoint is the host-side eRPC route (hostname-restricted to
	// obol.stack); append /<network> (the chain alias).
	ERPCEndpoint = "http://obol.stack:8080/rpc"
)
View Source
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

View Source
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

func AddCustomRPC(cfg *config.Config, chainID int, chainName, endpoint string, readOnly bool) error

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 Ago added in v0.17.0

func Ago(d time.Duration) string

Ago renders a duration as "45s", "3m", "2h", "4d".

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

func DefaultChainListFetcher() ([]byte, error)

DefaultChainListFetcher fetches from the real ChainList API.

func Delete

func Delete(cfg *config.Config, u *ui.UI, deploymentIdentifier string) error

Delete removes the network deployment configuration and cluster resources

func DeregisterERPCUpstream added in v0.3.2

func DeregisterERPCUpstream(cfg *config.Config, networkType, id string) error

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

func FormatBytes(n uint64) string

FormatBytes renders bytes as "412 GiB" / "1.1 TiB".

func GrafanaNodeURL added in v0.17.0

func GrafanaNodeURL(namespace string) string

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 List

func List(cfg *config.Config, u *ui.UI) error

List displays all available networks from the embedded filesystem

func ListDeployments added in v0.15.0

func ListDeployments(cfg *config.Config) []string

ListDeployments returns every installed local network deployment as "<network>/<id>", sorted.

func ListInstanceIDs added in v0.5.0

func ListInstanceIDs(cfg *config.Config) ([]string, error)

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

func LocalUpstreamID(networkType, id string) string

LocalUpstreamID is the eRPC upstream id RegisterERPCUpstream uses for a local deployment.

func ProbeBeaconAPI added in v0.16.0

func ProbeBeaconAPI(ctx context.Context, client *http.Client, base string, cl *ConsensusStatus)

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

func ProbeExecutionAPI(ctx context.Context, client *http.Client, base string, el *ExecutionStatus)

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

func ReconcileERPCOverlay(cfg *config.Config, u *ui.UI)

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

func ReconcileRecordedRPCs(cfg *config.Config, u *ui.UI)

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

func RegisterERPCUpstream(cfg *config.Config, networkType, id string) error

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

func RemovePublicRPCs(cfg *config.Config, chainID int) error

RemovePublicRPCs removes all ChainList RPCs for a chain from the eRPC ConfigMap.

func ResetERPC added in v0.14.0

func ResetERPC(cfg *config.Config, u *ui.UI) error

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

func ResolveChainID(nameOrID string) (int, string, error)

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

func ResumeInstalled(cfg *config.Config, u *ui.UI) error

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

func SetERPC(cfg *config.Config, u *ui.UI, path string) error

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

func Start(cfg *config.Config, u *ui.UI, identifier string) error

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

func Stop(cfg *config.Config, u *ui.UI, identifier string) error

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 Sync

func Sync(cfg *config.Config, u *ui.UI, deploymentIdentifier string) error

Sync deploys or updates a network configuration to the cluster using helmfile

func SyncAll added in v0.3.2

func SyncAll(cfg *config.Config, u *ui.UI) error

SyncAll syncs all installed network deployments found in the config directory.

func VerdictUnhealthy added in v0.17.0

func VerdictUnhealthy(state string) bool

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

type ChainListFetcher func() ([]byte, error)

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

func HardforkByBlock(block uint64) *Hardfork

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

func HardforkByName(name string) *Hardfork

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

type RPCUpstreamInfo struct {
	ID       string
	Endpoint string
	ChainID  int
}

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

type RecordedCustom struct {
	Endpoint string `yaml:"endpoint"`
	ReadOnly bool   `yaml:"readOnly"`
}

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) MarshalJSON added in v0.17.0

func (s StorageStatus) MarshalJSON() ([]byte, error)

MarshalJSON writes a size that could not be read at all (partial, and nothing counted) as null rather than 0, matching "unknown" in the human output.

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).

func (SyncStage) Pct added in v0.17.0

func (s SyncStage) Pct() (float64, bool)

Pct is Block/Target in percent (one decimal), or false without a target.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL