package main import ( "encoding/xml" "flag" "fmt" "lux/crypto" "lux/proto" "os" "strings" ) var isNode bool var isHost bool var isRpc bool var configPath string var rpcPath string var bootstrap bool var justNodeId bool type NodeConfig struct { XMLName xml.Name `xml:"node"` KeyStore string `xml:"keystore"` ID string `xml:"id"` Interior []string `xml:"interior"` Exterior []string `xml:"exterior"` Neighbors []struct { XMLName xml.Name `xml:"neighbor"` ID string `xml:"id"` Address string `xml:"address"` } `xml:"neighbor"` } func bootstrapNode() { xmlBytes, err := os.ReadFile(configPath) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } var config NodeConfig if err := xml.Unmarshal(xmlBytes, &config); err != nil { fmt.Fprintf(os.Stderr, "failed to parse xml: %v", err) os.Exit(1) } // create keystore, generate node key ks := crypto.NewLuxKeyStore(config.KeyStore) nodeKey, err := crypto.NewLuxKey(proto.LuxTypeNode) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if err := ks.Put(nodeKey); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if justNodeId { fmt.Println(nodeKey.Id.String()) } else { fmt.Printf("Your node key ID is: %s\nAdd %s to your node config!\n", nodeKey.Id.String(), nodeKey.Id.String()) } } func main() { // first, we need to determine who we are: node, host or rpc. // determine by executable name (lux binary will be symlinked to lux-node, lux-host, luc-rpc), // or by explicit cli flag (--node, --host, --rpc) flag.BoolVar(&isNode, "node", false, "LUX node") flag.BoolVar(&isHost, "host", false, "LUX host") flag.BoolVar(&isRpc, "rpc", false, "RPC tool") flag.StringVar(&configPath, "config", "", "node or host config") flag.StringVar(&rpcPath, "rpc-path", "", "path to RPC UNIX socket or TCP socket, must be in unix:// or tcp:// form") flag.BoolVar(&bootstrap, "bootstrap", false, "bootstrap node keystore. config must be specified") flag.BoolVar(&justNodeId, "just-node-id", false, "when bootstrapping only output node id to stdout") flag.Parse() if !isNode && !isHost && !isRpc { // determine by argv[0] if strings.Contains(os.Args[0], "node") { isNode = true } else if strings.Contains(os.Args[0], "host") { isHost = true } else if strings.Contains(os.Args[0], "rpc") { isRpc = true } } if (isNode || isHost) && configPath == "" { fmt.Fprintln(os.Stderr, "must provide config path") os.Exit(1) } else if isRpc && rpcPath == "" { fmt.Fprintln(os.Stderr, "must provide RPC socket path") os.Exit(1) } if isNode && bootstrap { bootstrapNode() return } }