Documentation
¶
Overview ¶
Package network resolves a (name, env) tuple to a runtime profile for booting, deploying to, snapshotting, and stopping a sovereign-L1 node.
The source of truth is each network's `chain.yaml` discovered under $LUX_NETWORK_PATH (default ~/work/lux/universe:~/work/zoo/universe:…). One typed schema, one parse path, one resolution rule — every CLI verb consumes the same Profile.
Identity at runtime: a network instance is uniquely identified by (name, env). At the wire that maps to (NetworkID, HTTPPort). Stop probes HTTPPort and verifies NetworkID matches before signaling: identity by what-the-node-IS, not by what-PID-it-was.
Index ¶
- Constants
- func DefaultPath() string
- func HashGenesis(data []byte) string
- func PIDOnPort(port int) (int, error)
- func ParseRef(ref string) (string, string, error)
- type Branding
- type Chain
- type Env
- type Lock
- type Meta
- type Profile
- func (p *Profile) LockPath() string
- func (p *Profile) PIDFilePath() string
- func (p *Profile) Probe(ctx context.Context) (matches bool, foundID uint32, err error)
- func (p *Profile) ReadLock() (*Lock, error)
- func (p *Profile) Stop(ctx context.Context, gracePeriod time.Duration) error
- func (p Profile) String() string
- func (p *Profile) VerifyOrCreate(genesisHash string) error
- func (p *Profile) WaitHealthy(ctx context.Context, timeout time.Duration) error
- func (p *Profile) WriteLock(genesisHash string) error
- type Registry
- type Runtime
- type Spec
- type Token
Constants ¶
const EnvVar = "LUX_NETWORK_PATH"
EnvVar is the colon-separated path of universe directories scanned for chain.yaml — same shape as $PATH.
const SchemaVersion = "1"
Variables ¶
This section is empty.
Functions ¶
func DefaultPath ¶
func DefaultPath() string
DefaultPath is the workspace convention: ~/work/<name>/universe.
func HashGenesis ¶
HashGenesis returns the lowercased hex sha256 of the genesis blob — the value that goes in chain.lock to bind a data-dir to its genesis.
Types ¶
type Branding ¶
type Branding struct {
DisplayName string `yaml:"displayName"`
LegalEntity string `yaml:"legalEntity"`
Domains map[string]any `yaml:"domains"`
}
Branding is the UI-facing `brand:` block (display name, colors, domains). Distinct from package name — kept because the YAML key is historical.
type Chain ¶
type Chain struct {
Name string `yaml:"name"`
Slug string `yaml:"slug"`
VMType string `yaml:"vmType"`
Description string `yaml:"description"`
RPCPath string `yaml:"rpcPath"`
WSPath string `yaml:"wsPath"`
GenesisFile string `yaml:"genesisFile"`
}
Chain is one entry in `chains:`.
type Env ¶
type Env struct {
NetworkID uint32 `yaml:"networkID"`
PrimaryEvmChainID uint64 `yaml:"primaryEvmChainID"`
HTTPPort int `yaml:"httpPort"`
StakingPort int `yaml:"stakingPort"`
GenesisFile string `yaml:"genesisFile"` // relative to chain.yaml dir
RPCUrl string `yaml:"rpcUrl"`
WSUrl string `yaml:"wsUrl"`
Explorer string `yaml:"explorer"`
Cluster string `yaml:"cluster"`
Namespace string `yaml:"namespace"`
ImageTag string `yaml:"imageTag"`
}
Env is one `networks.<env>:` block.
NetworkID and PrimaryEvmChainID are DISTINCT identifiers:
- NetworkID (uint32) is the validator-wire ID — --network-id flag, P-chain handshake, info.getNetworkID.
- PrimaryEvmChainID (uint64) is the C-chain EIP-155 ID — eth_chainId, MetaMask, EIP-155 tx signing.
Lux brand keeps them DELIBERATELY DISTINCT (NID 1 / EVM 96369). Sovereign-L1 brand forks (Zoo, Hanzo, Pars, Osage, Liquidity) collapse them to one ID per env per L1 by convention.
type Lock ¶
type Lock struct {
Version string `json:"version"`
Name string `json:"name"`
Env string `json:"env"`
NetworkID uint32 `json:"networkID"`
PrimaryEvmChainID uint64 `json:"primaryEvmChainID"`
HTTPPort int `json:"httpPort"`
StakingPort int `json:"stakingPort"`
GenesisHash string `json:"genesisHash"`
CreatedAt string `json:"createdAt"`
}
Lock is the on-disk invariant manifest in <DataDir>/chain.lock. First-boot writes it; subsequent boots reject mismatches.
type Meta ¶
type Meta struct {
Name string `yaml:"name"`
Slug string `yaml:"slug"`
Type string `yaml:"type"` // l1 | l2 | l3
Parent string `yaml:"parent"` // null for sovereign L1
Validators int `yaml:"validators"`
DBType string `yaml:"dbType"`
Compression string `yaml:"compression"`
}
Meta is the top-level `network:` block.
type Profile ¶
type Profile struct {
Name string // network name slug (zoo, lux, hanzo…)
Env string // mainnet | testnet | devnet | localnet
NetworkID uint32 // validator wire / --network-id
PrimaryEvmChainID uint64 // C-chain EIP-155 / eth_chainId
HTTPPort int
StakingPort int
DataDir string // absolute
LogDir string // absolute (always <dataDir>/logs)
GenesisFile string // absolute, may be empty (use luxd embedded)
RPCUrl string // remote (production) RPC if applicable
LocalRPCUrl string // http://127.0.0.1:<httpPort>/v1/bc/C/rpc
SnapshotDir string // absolute
SnapshotName string // expanded
ServiceLabel string // expanded, e.g. ai.lux.zoo.devnet
LogLevel string
}
Profile is what every verb consumes. Resolved from a Spec + env string by Resolve(); all paths absolute, all defaults applied.
func Resolve ¶
Resolve maps "name/env" to a fully-expanded Profile via the registry. All paths absolute, all defaults applied.
func ResolveSpec ¶
ResolveSpec resolves a Profile given an already-parsed Spec.
func (*Profile) PIDFilePath ¶
PIDFilePath is <DataDir>/luxd.pid (fallback identity record).
func (*Profile) Probe ¶
Probe asks the local node at p.HTTPPort what its NetworkID is. Returns (matches=true) only if the response equals p.NetworkID. A nil error with matches=false means a node is up but it isn't ours.
func (*Profile) Stop ¶
Stop signals the node owning p.HTTPPort, but only after verifying (via Probe) that the responder is OUR (name, env). On verification failure we refuse — better to leave a stranger alone than to murder the wrong process.
func (*Profile) VerifyOrCreate ¶
VerifyOrCreate inspects DataDir. If a lock exists it must match the profile (NetworkID + genesisHash). If absent and DataDir is empty, we write a fresh lock. If absent but DataDir has chain data, the dir is orphaned — refuse to mount so we don't corrupt unknown state.
func (*Profile) WaitHealthy ¶
WaitHealthy polls /v1/health and /v1/info until the C-chain responds with the expected NetworkID, or timeout elapses.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds networks discovered from $LUX_NETWORK_PATH.
func Discover ¶
Discover scans $LUX_NETWORK_PATH for chain.yaml files. Networks later in the path do NOT override earlier ones — first-wins, like $PATH. Unreadable / malformed files are skipped with a warning.
type Runtime ¶
type Runtime struct {
DataDirTemplate string `yaml:"dataDirTemplate"`
SnapshotDir string `yaml:"snapshotDir"`
SnapshotNameTemplate string `yaml:"snapshotNameTemplate"`
ServiceLabelTemplate string `yaml:"serviceLabelTemplate"`
LogLevel string `yaml:"logLevel"`
}
Runtime declares the templates the CLI expands. Path values support {name}, {env}, {networkID}, {primaryEvmChainID}, {httpPort}, {stakingPort} substitution.
type Spec ¶
type Spec struct {
Version string `yaml:"version"`
Network Meta `yaml:"network"`
Networks map[string]Env `yaml:"networks"`
Chains []Chain `yaml:"chains"`
Token Token `yaml:"token"`
Brand Branding `yaml:"brand"`
Runtime Runtime `yaml:"runtime"`
Precompiles []map[string]any `yaml:"precompiles"`
// SourcePath is the absolute path to the chain.yaml file. All
// relative paths in the file resolve against its directory.
SourcePath string `yaml:"-"`
}
Spec is the parsed chain.yaml for one network universe.