Files
zeekayandHanzo Dev dcf0f9e701 The fd-limit the operator asked for was read and then not used
--fd-limit is parsed into the node config and documented in config.md, and
three shipped profiles set it: 512 in low and dev-light, 65536 in max. The
only code that ever read it is app/app.go, in a package nothing imports.
The daemon passed the package constant instead, so every node raised its
descriptor limit to 32768 whatever the operator wrote.

Measured: `luxd --fd-limit=2000000` on this commit exits 1 with
"error fd-limit: (2000000) greater than max: (1048576)"; the same argument
before it produced no fd-limit line at all and went on to boot.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-15 11:39:32 -07:00

105 lines
2.5 KiB
Go

// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// luxd — Lux Network node daemon.
//
// Entry point for the Lux primary-network node binary. Loads configuration
// from CLI flags + config files via Viper, constructs a [node.Node], and
// dispatches the main event loop.
package main
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
"syscall"
"github.com/luxfi/log"
"github.com/luxfi/node/config"
"github.com/luxfi/node/node"
"github.com/luxfi/node/version"
"github.com/luxfi/sys/ulimit"
)
const Header = `
▼▼▼▼▼
▼▼▼
▼
`
func main() {
if exitCode := run(os.Args[1:]); exitCode != 0 {
os.Exit(exitCode)
}
}
func run(args []string) int {
// --version short-circuit
for _, a := range args {
if a == "--version" || a == "-v" {
fmt.Println(version.CurrentApp.String())
return 0
}
}
fmt.Print(Header)
// Parse CLI + config file via Viper.
fs := config.BuildFlagSet()
v, err := config.BuildViper(fs, args)
if err != nil {
fmt.Fprintln(os.Stderr, "luxd: failed to parse config:", err)
return 1
}
cfg, err := config.GetNodeConfig(v)
if err != nil {
fmt.Fprintln(os.Stderr, "luxd: failed to load node config:", err)
return 1
}
// Logger.
infoLevel, _ := log.ToLevel("info")
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: infoLevel,
LogLevel: infoLevel,
})
logger, err := logFactory.Make("node")
if err != nil {
fmt.Fprintln(os.Stderr, "luxd: failed to construct logger:", err)
return 1
}
// Bump file descriptor limit early; node + its plugins open many sockets.
// The number is --fd-limit, which carries the default when nobody set it.
// Reading the constant here instead left the flag, its documentation and
// the three profiles that set it with nothing to act on.
if err := ulimit.Set(cfg.FdLimit, logger); err != nil {
logger.Error("failed to set fd limit", "error", err)
return 1
}
// Construct the node.
n, err := node.New(&cfg, logFactory, logger)
if err != nil {
logger.Error("failed to construct node", "error", err)
return 1
}
// Run dispatch loop with signal-driven shutdown.
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
go func() {
<-ctx.Done()
logger.Info("received shutdown signal")
n.Shutdown(0)
}()
if err := n.Dispatch(); err != nil && !errors.Is(err, context.Canceled) {
logger.Error("dispatch returned error", "error", err)
return 1
}
return n.ExitCode()
}