mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
ConfigSpec.JSON() exports the flag specification as JSON. Duration-typed default values (e.g. consensus timeouts) need to render as integer nanoseconds for v1-compatible consumers and so the embedded JSON fixtures roundtrip. Pass jsonv1.FormatDurationAsNano(true) at the Marshal site.
221 lines
7.3 KiB
Go
221 lines
7.3 KiB
Go
// Copyright (C) 2022-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package spec provides a machine-readable specification of all luxd configuration flags.
|
|
// This is the single source of truth for configuration - all consumers (CLI, SDK, netrunner)
|
|
// should derive their flag knowledge from this spec.
|
|
package spec
|
|
|
|
import (
|
|
"github.com/go-json-experiment/json"
|
|
jsonv1 "github.com/go-json-experiment/json/v1"
|
|
"github.com/go-json-experiment/json/jsontext"
|
|
"time"
|
|
)
|
|
|
|
// FlagType represents the type of a configuration flag.
|
|
type FlagType string
|
|
|
|
const (
|
|
TypeBool FlagType = "bool"
|
|
TypeInt FlagType = "int"
|
|
TypeUint FlagType = "uint"
|
|
TypeUint64 FlagType = "uint64"
|
|
TypeFloat64 FlagType = "float64"
|
|
TypeDuration FlagType = "duration"
|
|
TypeString FlagType = "string"
|
|
TypeStringSlice FlagType = "string-slice"
|
|
TypeIntSlice FlagType = "int-slice"
|
|
TypeStringToString FlagType = "string-to-string"
|
|
)
|
|
|
|
// Category groups related configuration flags.
|
|
type Category string
|
|
|
|
const (
|
|
CategoryProcess Category = "process"
|
|
CategoryNode Category = "node"
|
|
CategoryDatabase Category = "database"
|
|
CategoryNetwork Category = "network"
|
|
CategoryConsensus Category = "consensus"
|
|
CategoryStaking Category = "staking"
|
|
CategoryHTTP Category = "http"
|
|
CategoryAPI Category = "api"
|
|
CategoryHealth Category = "health"
|
|
CategoryLogging Category = "logging"
|
|
CategoryThrottler Category = "throttler"
|
|
CategorySystem Category = "system"
|
|
CategoryBootstrap Category = "bootstrap"
|
|
CategoryChain Category = "chain"
|
|
CategoryProfile Category = "profile"
|
|
CategoryMetrics Category = "metrics"
|
|
CategoryGenesis Category = "genesis"
|
|
CategoryFees Category = "fees"
|
|
CategoryIndex Category = "index"
|
|
CategoryTracing Category = "tracing"
|
|
CategoryPOA Category = "poa"
|
|
CategoryDev Category = "dev"
|
|
)
|
|
|
|
// FlagSpec describes a single configuration flag.
|
|
type FlagSpec struct {
|
|
// Key is the flag name (e.g., "network-id", "log-level")
|
|
Key string `json:"key"`
|
|
|
|
// Type is the flag's data type
|
|
Type FlagType `json:"type"`
|
|
|
|
// Default is the default value (nil if no default)
|
|
Default interface{} `json:"default,omitempty"`
|
|
|
|
// Description is the human-readable documentation
|
|
Description string `json:"description"`
|
|
|
|
// Category groups related flags for organization
|
|
Category Category `json:"category"`
|
|
|
|
// Deprecated indicates if this flag is deprecated
|
|
Deprecated bool `json:"deprecated,omitempty"`
|
|
|
|
// DeprecatedMessage explains what to use instead
|
|
DeprecatedMessage string `json:"deprecated_message,omitempty"`
|
|
|
|
// ReplacedBy is the key of the replacement flag (if deprecated)
|
|
ReplacedBy string `json:"replaced_by,omitempty"`
|
|
|
|
// Required indicates if this flag must be explicitly set
|
|
Required bool `json:"required,omitempty"`
|
|
|
|
// Sensitive indicates if the value should be masked in logs
|
|
Sensitive bool `json:"sensitive,omitempty"`
|
|
|
|
// Constraints contains validation rules
|
|
Constraints *Constraints `json:"constraints,omitempty"`
|
|
|
|
// Since indicates when this flag was introduced (version string)
|
|
Since string `json:"since,omitempty"`
|
|
}
|
|
|
|
// Constraints defines validation rules for a flag.
|
|
type Constraints struct {
|
|
// Min is the minimum value (for numeric types)
|
|
Min interface{} `json:"min,omitempty"`
|
|
|
|
// Max is the maximum value (for numeric types)
|
|
Max interface{} `json:"max,omitempty"`
|
|
|
|
// Enum lists allowed values (for string types)
|
|
Enum []string `json:"enum,omitempty"`
|
|
|
|
// Pattern is a regex pattern (for string types)
|
|
Pattern string `json:"pattern,omitempty"`
|
|
|
|
// RequiredWith lists flags that must also be set
|
|
RequiredWith []string `json:"required_with,omitempty"`
|
|
|
|
// ConflictsWith lists flags that cannot be set together
|
|
ConflictsWith []string `json:"conflicts_with,omitempty"`
|
|
}
|
|
|
|
// ConfigSpec is the complete specification of all luxd configuration flags.
|
|
type ConfigSpec struct {
|
|
// Version is the spec version (semver)
|
|
Version string `json:"version"`
|
|
|
|
// NodeVersion is the luxd version this spec was generated from
|
|
NodeVersion string `json:"node_version"`
|
|
|
|
// GeneratedAt is when this spec was generated (RFC3339)
|
|
GeneratedAt string `json:"generated_at"`
|
|
|
|
// Flags contains all flag specifications
|
|
Flags []FlagSpec `json:"flags"`
|
|
|
|
// Categories lists all categories with descriptions
|
|
Categories map[Category]string `json:"categories"`
|
|
}
|
|
|
|
// Spec returns the complete configuration specification.
|
|
// This is the single source of truth for all luxd flags.
|
|
func Spec() *ConfigSpec {
|
|
return &ConfigSpec{
|
|
Version: "1.0.0",
|
|
NodeVersion: "1.22.18",
|
|
GeneratedAt: time.Now().UTC().Format(time.RFC3339),
|
|
Flags: allFlags(),
|
|
Categories: categoryDescriptions(),
|
|
}
|
|
}
|
|
|
|
// categoryDescriptions returns descriptions for all categories.
|
|
func categoryDescriptions() map[Category]string {
|
|
return map[Category]string{
|
|
CategoryProcess: "Process-level flags (version, help)",
|
|
CategoryNode: "Node configuration (data directory, plugins)",
|
|
CategoryDatabase: "Database configuration (type, path, per-chain)",
|
|
CategoryNetwork: "P2P networking (timeouts, throttling, peers)",
|
|
CategoryConsensus: "Consensus parameters (sample size, quorum, thresholds)",
|
|
CategoryStaking: "Staking configuration (keys, sybil protection)",
|
|
CategoryHTTP: "HTTP server configuration (host, port, TLS)",
|
|
CategoryAPI: "API enablement (admin, info, keystore, metrics)",
|
|
CategoryHealth: "Health check configuration (frequency, thresholds)",
|
|
CategoryLogging: "Logging configuration (level, format, rotation)",
|
|
CategoryThrottler: "Rate limiting and resource throttling",
|
|
CategorySystem: "System resource tracking (CPU, disk, memory)",
|
|
CategoryBootstrap: "Bootstrap and state sync configuration",
|
|
CategoryChain: "Chain-specific configuration directories",
|
|
CategoryProfile: "Performance profiling configuration",
|
|
CategoryMetrics: "Metrics collection and reporting",
|
|
CategoryGenesis: "Genesis file and upgrade configuration",
|
|
CategoryFees: "Transaction fee configuration",
|
|
CategoryIndex: "Indexer configuration",
|
|
CategoryTracing: "OpenTelemetry tracing configuration",
|
|
CategoryPOA: "Proof of Authority mode configuration",
|
|
CategoryDev: "Development and testing flags",
|
|
}
|
|
}
|
|
|
|
// GetFlag returns the spec for a specific flag, or nil if not found.
|
|
func (s *ConfigSpec) GetFlag(key string) *FlagSpec {
|
|
for i := range s.Flags {
|
|
if s.Flags[i].Key == key {
|
|
return &s.Flags[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// FlagsByCategory returns all flags in a specific category.
|
|
func (s *ConfigSpec) FlagsByCategory(cat Category) []FlagSpec {
|
|
var result []FlagSpec
|
|
for _, f := range s.Flags {
|
|
if f.Category == cat {
|
|
result = append(result, f)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// DeprecatedFlags returns all deprecated flags.
|
|
func (s *ConfigSpec) DeprecatedFlags() []FlagSpec {
|
|
var result []FlagSpec
|
|
for _, f := range s.Flags {
|
|
if f.Deprecated {
|
|
result = append(result, f)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// JSON returns the spec as formatted JSON.
|
|
func (s *ConfigSpec) JSON() ([]byte, error) {
|
|
return json.Marshal(s, jsontext.WithIndent(" "), jsonv1.FormatDurationAsNano(true))
|
|
}
|
|
|
|
// ValidateValue checks if a value is valid for a flag.
|
|
func (f *FlagSpec) ValidateValue(value interface{}) error {
|
|
// Type checking and constraint validation would go here
|
|
// For now, return nil (valid)
|
|
return nil
|
|
}
|