node

package
v1.0.0-rc0 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package node provides node management implementations.

Index

Constants

View Source
const (
	// DefaultDockerImage is the default Docker image for running nodes.
	DefaultDockerImage = "stablelabs/stabled:latest"

	// DockerStopTimeout is the timeout for gracefully stopping a container.
	DockerStopTimeout = 30 * time.Second
)
View Source
const (
	// HealthCheckTimeout is the timeout for health check requests.
	HealthCheckTimeout = 5 * time.Second

	// HealthCheckRetries is the number of retries for health checks.
	HealthCheckRetries = 3

	// HealthCheckInterval is the interval between health check retries.
	HealthCheckInterval = 1 * time.Second
)
View Source
const (
	// DefaultLocalBinary is the fallback binary name when no specific name is provided.
	// Prefer using network module's BinaryName() for network-specific binaries.
	DefaultLocalBinary = "binary"

	// LocalStopTimeout is the timeout for gracefully stopping a local process.
	LocalStopTimeout = 30 * time.Second
)

Variables

This section is empty.

Functions

func ContainerNameForIndex deprecated

func ContainerNameForIndex(index int) string

ContainerNameForIndex returns the Docker container name for a node index.

Deprecated: Use ContainerNameForNetwork instead for multi-network support.

func ContainerNameForNetwork

func ContainerNameForNetwork(networkName string, index int) string

ContainerNameForNetwork returns the Docker container name for a node with network name.

func ExtractEVMChainID

func ExtractEVMChainID(chainID string) string

ExtractEVMChainID extracts the EVM chain ID from a Cosmos chain ID. For example, "stable_988-1" returns "988".

func FollowDockerLogs

func FollowDockerLogs(ctx context.Context, containerName string) error

FollowDockerLogs follows the logs of a Docker container.

func FollowLocalLogs

func FollowLocalLogs(ctx context.Context, logPath string) error

FollowLocalLogs follows a local log file using tail -f.

func GetBlockHeight

func GetBlockHeight(ctx context.Context, node *Node) (int64, error)

GetBlockHeight returns the current block height of a node.

func GetDockerLogs

func GetDockerLogs(ctx context.Context, containerName string, lines int) ([]string, error)

GetDockerLogs retrieves the last N lines from a Docker container's logs.

func GetPeerCount

func GetPeerCount(ctx context.Context, node *Node) (int, error)

GetPeerCount returns the number of peers connected to a node.

func IsDockerAvailable

func IsDockerAvailable(ctx context.Context) bool

IsDockerAvailable checks if Docker is available and running.

func IsLocalBinaryAvailable

func IsLocalBinaryAvailable(binaryPath string) bool

IsLocalBinaryAvailable checks if the local binary is available at the given path. For local mode, the binary must be an absolute path (e.g., ~/.devnet-builder/bin/stabled).

func IsNodeResponding

func IsNodeResponding(ctx context.Context, node *Node) bool

IsNodeResponding checks if a node's RPC endpoint is responding.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error is a NotFoundError.

func StreamLogs

func StreamLogs(ctx context.Context, reader io.Reader) error

StreamLogs streams logs from a reader to stdout.

func WaitForAllNodesHealthy

func WaitForAllNodesHealthy(ctx context.Context, nodes []*Node, timeout time.Duration) error

WaitForAllNodesHealthy waits for all nodes to become healthy.

func WaitForHealthy

func WaitForHealthy(ctx context.Context, node *Node, timeout time.Duration) error

WaitForHealthy waits for a node to become healthy.

Types

type AlreadyRunningError

type AlreadyRunningError struct {
	NodeIndex int
}

AlreadyRunningError is returned when trying to start an already running node.

func (*AlreadyRunningError) Error

func (e *AlreadyRunningError) Error() string

type ContainerConfig

type ContainerConfig struct {
	Node           *Node              // Node to start
	GenesisPath    string             // Path to genesis file
	NetworkID      string             // Docker network ID (empty = host networking)
	ResourceLimits *ResourceLimits    // Resource constraints (nil = no limits)
	HealthCheck    *HealthCheckConfig // Health check config (nil = no health check)
}

ContainerConfig holds configuration for starting a Docker container

type DockerManager

type DockerManager struct {
	Image      string
	EVMChainID string
	Logger     *output.Logger
}

DockerManager manages nodes running in Docker containers.

func NewDockerManager

func NewDockerManager(image string, logger *output.Logger) *DockerManager

NewDockerManager creates a new DockerManager.

func NewDockerManagerWithEVMChainID

func NewDockerManagerWithEVMChainID(image string, evmChainID string, logger *output.Logger) *DockerManager

NewDockerManagerWithEVMChainID creates a new DockerManager with EVM chain ID.

func (*DockerManager) Export

func (m *DockerManager) Export(ctx context.Context, nodeDir, destPath string) error

Export runs `stabled export` to export the current state as genesis.

func (*DockerManager) FollowLogs

func (m *DockerManager) FollowLogs(ctx context.Context, node *Node, tail int) (*exec.Cmd, error)

FollowLogs streams logs from a Docker container.

func (*DockerManager) GetLogs

func (m *DockerManager) GetLogs(ctx context.Context, node *Node, tail int, since string) (string, error)

GetLogs retrieves logs from a Docker container.

func (*DockerManager) GetNodeID

func (m *DockerManager) GetNodeID(ctx context.Context, nodeDir string) (string, error)

GetNodeID retrieves the node ID using `stabled comet show-node-id`.

func (*DockerManager) Init

func (m *DockerManager) Init(ctx context.Context, nodeDir, moniker, chainID string) error

Init runs `stabled init` for a node in Docker.

func (*DockerManager) IsRunning

func (m *DockerManager) IsRunning(ctx context.Context, node *Node) bool

IsRunning checks if a Docker container is running.

func (*DockerManager) PullImage

func (m *DockerManager) PullImage(ctx context.Context) error

PullImage pulls the Docker image if not present.

func (*DockerManager) Start

func (m *DockerManager) Start(ctx context.Context, node *Node, genesisPath string) error

Start starts a node in a Docker container (backward compatible).

func (*DockerManager) StartWithConfig

func (m *DockerManager) StartWithConfig(ctx context.Context, config *ContainerConfig) error

StartWithConfig starts a node in a Docker container with advanced configuration.

func (*DockerManager) Stop

func (m *DockerManager) Stop(ctx context.Context, node *Node, timeout time.Duration) error

Stop stops a running Docker container.

func (*DockerManager) ValidateImage

func (m *DockerManager) ValidateImage(ctx context.Context) error

ValidateImage validates that a docker image exists locally or can be pulled. First checks if the image exists locally to avoid unnecessary pull attempts. Returns a clear error message if the image cannot be found or pulled.

type DockerNodeManager

type DockerNodeManager struct {
	// contains filtered or unexported fields
}

DockerNodeManager implements NodeManager for Docker container execution.

func NewDockerNodeManager

func NewDockerNodeManager(
	node *Node,
	image string,
	evmChainID string,
	genesisPath string,
	logger *output.Logger,
) *DockerNodeManager

NewDockerNodeManager creates a new DockerNodeManager.

func (*DockerNodeManager) GetContainerID

func (m *DockerNodeManager) GetContainerID() string

GetContainerID returns the container ID.

func (*DockerNodeManager) GetPID

func (m *DockerNodeManager) GetPID() *int

GetPID returns nil for Docker nodes.

func (*DockerNodeManager) IsRunning

func (m *DockerNodeManager) IsRunning() bool

IsRunning checks if the node is running.

func (*DockerNodeManager) LogPath

func (m *DockerNodeManager) LogPath() string

LogPath returns empty for Docker nodes (logs accessed via docker logs).

func (*DockerNodeManager) Logs

func (m *DockerNodeManager) Logs(lines int) ([]string, error)

Logs retrieves the last N lines of logs.

func (*DockerNodeManager) Start

func (m *DockerNodeManager) Start(ctx context.Context) error

Start starts the node.

func (*DockerNodeManager) Stop

func (m *DockerNodeManager) Stop(ctx context.Context, timeout time.Duration) error

Stop stops the node.

type FactoryConfig

type FactoryConfig struct {
	// Mode determines whether to use Docker or local execution.
	Mode types.ExecutionMode

	// BinaryPath is the path to the stabled binary (local mode only).
	// If empty, defaults to homeDir/bin/stabled.
	BinaryPath string

	// DockerImage is the Docker image to use (docker mode only).
	// If empty, defaults to DefaultDockerImage.
	DockerImage string

	// EVMChainID is the EVM chain ID (optional, used for --evm.evm-chain-id flag).
	EVMChainID string

	// Logger is the output logger. If nil, uses DefaultLogger.
	Logger *output.Logger
}

FactoryConfig contains configuration for creating a NodeManager.

func (*FactoryConfig) Validate

func (c *FactoryConfig) Validate() error

Validate checks if the configuration is valid.

type HealthCheckConfig

type HealthCheckConfig struct {
	Interval time.Duration // Interval between health checks
	Timeout  time.Duration // Timeout for each health check
	Retries  int           // Number of retries before marking unhealthy
}

HealthCheckConfig defines container health check parameters

func DefaultHealthCheckConfig

func DefaultHealthCheckConfig() HealthCheckConfig

DefaultHealthCheckConfig returns default health check configuration

type ImagePullError

type ImagePullError struct {
	Image   string
	Message string
	Output  string
}

ImagePullError represents an error when pulling a docker image fails.

func (*ImagePullError) Error

func (e *ImagePullError) Error() string

type LocalManager

type LocalManager struct {
	Binary     string
	EVMChainID string
	Logger     *output.Logger
}

LocalManager manages nodes running as local processes.

func NewLocalManager

func NewLocalManager(binary string, logger *output.Logger) *LocalManager

NewLocalManager creates a new LocalManager.

func NewLocalManagerWithEVMChainID

func NewLocalManagerWithEVMChainID(binary string, evmChainID string, logger *output.Logger) *LocalManager

NewLocalManagerWithEVMChainID creates a new LocalManager with EVM chain ID.

func (*LocalManager) GetLogs

func (m *LocalManager) GetLogs(ctx context.Context, node *Node, tail int) (string, error)

GetLogs reads logs from the log file.

func (*LocalManager) IsRunning

func (m *LocalManager) IsRunning(ctx context.Context, node *Node) bool

IsRunning checks if a local process is running.

func (*LocalManager) Start

func (m *LocalManager) Start(ctx context.Context, node *Node, genesisPath string) error

Start starts a node as a local process.

func (*LocalManager) Stop

func (m *LocalManager) Stop(ctx context.Context, node *Node, timeout time.Duration) error

Stop stops a running local process.

type LocalNodeManager

type LocalNodeManager struct {
	// contains filtered or unexported fields
}

LocalNodeManager implements NodeManager for local process execution.

func NewLocalNodeManager

func NewLocalNodeManager(
	node *Node,
	binaryPath string,
	evmChainID string,
	genesisPath string,
	logger *output.Logger,
) *LocalNodeManager

NewLocalNodeManager creates a new LocalNodeManager.

func (*LocalNodeManager) GetContainerID

func (m *LocalNodeManager) GetContainerID() string

GetContainerID returns empty for local nodes.

func (*LocalNodeManager) GetPID

func (m *LocalNodeManager) GetPID() *int

GetPID returns the process ID.

func (*LocalNodeManager) IsRunning

func (m *LocalNodeManager) IsRunning() bool

IsRunning checks if the node is running.

func (*LocalNodeManager) LogPath

func (m *LocalNodeManager) LogPath() string

LogPath returns the path to the log file.

func (*LocalNodeManager) Logs

func (m *LocalNodeManager) Logs(lines int) ([]string, error)

Logs retrieves the last N lines of logs.

func (*LocalNodeManager) Start

func (m *LocalNodeManager) Start(ctx context.Context) error

Start starts the node.

func (*LocalNodeManager) Stop

func (m *LocalNodeManager) Stop(ctx context.Context, timeout time.Duration) error

Stop stops the node.

type Node

type Node struct {
	// Identification
	Index int    `json:"index"` // 0-3
	Name  string `json:"name"`  // e.g., "node0", "node1"

	// Network Identity
	NetworkName string `json:"network_name,omitempty"` // e.g., "stable", "ault"
	BinaryName  string `json:"binary_name,omitempty"`  // e.g., "stabled", "aultd"

	// Paths
	HomeDir string `json:"home_dir"` // e.g., ~/.devnet-builder/devnet/node0

	// Network Ports
	Ports NodePorts `json:"ports"`

	// Process Management (local mode)
	PID     *int   `json:"pid,omitempty"`
	LogFile string `json:"log_file,omitempty"`

	// Container Management (docker mode)
	ContainerID   string `json:"container_id,omitempty"`
	ContainerName string `json:"container_name,omitempty"`

	// Validator Info
	ValidatorAddress string `json:"validator_address"`
	ValidatorPubKey  string `json:"validator_pubkey"`

	// Status
	Status NodeStatus `json:"status"`
}

Node represents a single validator node in the devnet.

func LoadNode

func LoadNode(homeDir string) (*Node, error)

LoadNode loads a node configuration from disk. Uses helpers.LoadJSON for consistent file I/O with structured error handling.

func NewNode

func NewNode(index int, homeDir string) *Node

NewNode creates a new Node with default values for the given index.

func (*Node) ConfigPath

func (n *Node) ConfigPath() string

ConfigPath returns the path to the node's config directory.

func (*Node) DataPath

func (n *Node) DataPath() string

DataPath returns the path to the node's data directory.

func (*Node) DockerContainerName

func (n *Node) DockerContainerName() string

DockerContainerName returns the Docker container name for this node.

func (*Node) EVMRPCURL

func (n *Node) EVMRPCURL() string

EVMRPCURL returns the EVM JSON-RPC endpoint URL.

func (*Node) GRPCURL

func (n *Node) GRPCURL() string

GRPCURL returns the gRPC endpoint URL.

func (*Node) IsRunning

func (n *Node) IsRunning() bool

IsRunning returns true if the node is in running state.

func (*Node) KeyringPath

func (n *Node) KeyringPath() string

KeyringPath returns the path to the node's keyring directory.

func (*Node) LogFilePath

func (n *Node) LogFilePath() string

LogFilePath returns the path to the log file (local mode). Uses the node's BinaryName for dynamic file naming.

func (*Node) NodeJSONPath

func (n *Node) NodeJSONPath() string

NodeJSONPath returns the path to the node.json file.

func (*Node) PIDFilePath

func (n *Node) PIDFilePath() string

PIDFilePath returns the path to the PID file (local mode). Uses the node's BinaryName for dynamic file naming.

func (*Node) RPCURL

func (n *Node) RPCURL() string

RPCURL returns the RPC endpoint URL.

func (*Node) Save

func (n *Node) Save() error

Save persists the node configuration to disk. Uses helpers.SaveJSON for consistent file I/O with automatic directory creation.

func (*Node) SetError

func (n *Node) SetError()

SetError marks the node as having an error.

func (*Node) SetRunning

func (n *Node) SetRunning(pid *int, containerID string)

SetRunning marks the node as running with the given process/container info.

func (*Node) SetStopped

func (n *Node) SetStopped()

SetStopped marks the node as stopped.

type NodeError

type NodeError struct {
	NodeIndex int
	Operation string
	Message   string
}

NodeError is returned when node operations fail.

func (*NodeError) Error

func (e *NodeError) Error() string

type NodeHealth

type NodeHealth struct {
	Index       int        `json:"index"`
	Name        string     `json:"name"`
	Status      NodeStatus `json:"status"`
	BlockHeight int64      `json:"block_height"`
	PeerCount   int        `json:"peer_count"`
	CatchingUp  bool       `json:"catching_up"`
	Error       string     `json:"error,omitempty"`
}

NodeHealth represents the health status of a node.

func CheckAllNodesHealth

func CheckAllNodesHealth(ctx context.Context, nodes []*Node) []*NodeHealth

CheckAllNodesHealth checks the health of all nodes.

func CheckHealth

func CheckHealth(ctx context.Context, node *Node) (*NodeHealth, error)

CheckHealth checks the health of a node via its RPC endpoint.

func CheckNodeHealth

func CheckNodeHealth(ctx context.Context, node *Node) *NodeHealth

CheckNodeHealth is an alias for CheckHealth that ignores errors. Always returns a valid NodeHealth struct.

type NodeManager

type NodeManager interface {
	// Start starts a node with the given genesis path.
	Start(ctx context.Context, node *Node, genesisPath string) error

	// Stop stops a running node with the given timeout.
	Stop(ctx context.Context, node *Node, timeout time.Duration) error

	// IsRunning checks if the node is currently running.
	IsRunning(ctx context.Context, node *Node) bool
}

NodeManager defines the interface for node lifecycle management. Both DockerManager and LocalManager implement this interface.

type NodeManagerFactory

type NodeManagerFactory struct {
	// contains filtered or unexported fields
}

NodeManagerFactory creates NodeManager instances based on execution mode. This provides a single point of truth for manager creation logic.

func NewNodeManagerFactory

func NewNodeManagerFactory(config FactoryConfig) *NodeManagerFactory

NewNodeManagerFactory creates a new NodeManagerFactory with the given configuration.

func (*NodeManagerFactory) Create

func (f *NodeManagerFactory) Create() (NodeManager, error)

Create creates a NodeManager based on the configured execution mode. Returns DockerManager for ModeDocker, LocalManager for ModeLocal.

func (*NodeManagerFactory) IsDocker

func (f *NodeManagerFactory) IsDocker() bool

IsDocker returns true if the factory is configured for Docker mode.

func (*NodeManagerFactory) IsLocal

func (f *NodeManagerFactory) IsLocal() bool

IsLocal returns true if the factory is configured for local mode.

func (*NodeManagerFactory) Mode

Mode returns the configured execution mode.

type NodePorts deprecated

type NodePorts = types.PortConfig

NodePorts is an alias to the canonical types.PortConfig.

Deprecated: Use types.PortConfig directly.

func DefaultPortsForNode deprecated

func DefaultPortsForNode(index int) NodePorts

DefaultPortsForNode returns the default ports for a node at the given index.

Deprecated: Use types.PortConfigForNode() directly.

type NodeStatus

type NodeStatus string

NodeStatus represents the current state of a node.

const (
	NodeStatusStopped  NodeStatus = "stopped"
	NodeStatusStarting NodeStatus = "starting"
	NodeStatusRunning  NodeStatus = "running"
	NodeStatusSyncing  NodeStatus = "syncing"
	NodeStatusError    NodeStatus = "error"
)

type NotFoundError

type NotFoundError struct {
	NodeIndex int
	HomeDir   string
}

NotFoundError is returned when a node is not found.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

type RPCNetInfoResponse

type RPCNetInfoResponse struct {
	Result struct {
		NPeers string `json:"n_peers"`
		Peers  []struct {
			NodeInfo struct {
				Moniker string `json:"moniker"`
			} `json:"node_info"`
		} `json:"peers"`
	} `json:"result"`
}

RPCNetInfoResponse represents the RPC /net_info response.

type RPCStatusResponse

type RPCStatusResponse struct {
	Result struct {
		SyncInfo struct {
			LatestBlockHeight string `json:"latest_block_height"`
			CatchingUp        bool   `json:"catching_up"`
		} `json:"sync_info"`
		NodeInfo struct {
			Network string `json:"network"`
			Moniker string `json:"moniker"`
		} `json:"node_info"`
	} `json:"result"`
}

RPCStatusResponse represents the RPC /status response.

type ResourceLimits

type ResourceLimits struct {
	Memory string // Memory limit (e.g., "2g", "512m")
	CPUs   string // CPU limit (e.g., "2.0", "0.5")
}

ResourceLimits defines container resource constraints

func DefaultResourceLimits

func DefaultResourceLimits() ResourceLimits

DefaultResourceLimits returns default resource limits for containers

Jump to

Keyboard shortcuts

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