From 48c88487e2f78e965a55f5833b36d885eb9a03dc Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:59:51 -0400 Subject: [PATCH] remove lazy initialize on node Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- app/app.go | 31 +++--- main/main.go | 8 +- node/node.go | 293 +++++++++++++++++++++++++-------------------------- 3 files changed, 168 insertions(+), 164 deletions(-) diff --git a/app/app.go b/app/app.go index 76cf137034b3..94a4f86afeae 100644 --- a/app/app.go +++ b/app/app.go @@ -54,11 +54,25 @@ type App interface { ExitCode() (int, error) } -func New(config node.Config) App { +func New(config node.Config) (App, error) { + logFactory := logging.NewFactory(config.LoggingConfig) + log, err := logFactory.Make("main") + if err != nil { + logFactory.Close() + return nil, err + } + + n, err := node.New(&config, logFactory, log) + if err != nil { + log.Stop() + logFactory.Close() + return nil, err + } + return &app{ config: config, - node: &node.Node{}, - } + node: n, + }, nil } func Run(app App) int { @@ -215,17 +229,6 @@ func (a *app) Start() error { // update our public IP, [p.config.IPUdater] is a no-op implementation. go a.config.IPUpdater.Dispatch(log) - if err := a.node.Initialize(&a.config, log, logFactory); err != nil { - log.Fatal("error initializing node", - zap.Error(err), - ) - mapper.UnmapAllPorts() - a.config.IPUpdater.Stop() - log.Stop() - logFactory.Close() - return err - } - // [p.ExitCode] will block until [p.exitWG.Done] is called a.exitWG.Add(1) go func() { diff --git a/main/main.go b/main/main.go index 5d85530177dd..36009e5c120a 100644 --- a/main/main.go +++ b/main/main.go @@ -9,7 +9,6 @@ import ( "os" "github.com/spf13/pflag" - "golang.org/x/term" "github.com/ava-labs/avalanchego/app" @@ -41,11 +40,16 @@ func main() { os.Exit(1) } - nodeApp := app.New(nodeConfig) // Create node wrapper if term.IsTerminal(int(os.Stdout.Fd())) { fmt.Println(app.Header) } + nodeApp, err := app.New(nodeConfig) // Create node wrapper + if err != nil { + fmt.Printf("couldn't start node: %s\n", err) + os.Exit(1) + } + exitCode := app.Run(nodeApp) os.Exit(exitCode) } diff --git a/node/node.go b/node/node.go index cad0073899b8..79831d7bb8fa 100644 --- a/node/node.go +++ b/node/node.go @@ -100,6 +100,151 @@ var ( errShuttingDown = errors.New("server shutting down") ) +func New(config *Config, logFactory logging.Factory, logger logging.Logger) (*Node, error) { + tlsCert := config.StakingTLSCert.Leaf + stakingCert := staking.CertificateFromX509(tlsCert) + if err := staking.ValidateCertificate(stakingCert); err != nil { + return nil, fmt.Errorf("invalid staking certificate: %w", err) + } + + n := &Node{} + + n.Log = logger + n.Config = config + n.ID = ids.NodeIDFromCert(stakingCert) + n.LogFactory = logFactory + n.DoneShuttingDown.Add(1) + + pop := signer.NewProofOfPossession(n.Config.StakingSigningKey) + logger.Info("initializing node", + zap.Stringer("version", version.CurrentApp), + zap.Stringer("nodeID", n.ID), + zap.Stringer("stakingKeyType", tlsCert.PublicKeyAlgorithm), + zap.Reflect("nodePOP", pop), + zap.Reflect("providedFlags", n.Config.ProvidedFlags), + zap.Reflect("config", n.Config), + ) + + var err error + n.VMFactoryLog, err = logFactory.Make("vm-factory") + if err != nil { + return nil, fmt.Errorf("problem creating vm logger: %w", err) + } + + n.VMManager = vms.NewManager(n.VMFactoryLog, config.VMAliaser) + + if err := n.initBootstrappers(); err != nil { // Configure the bootstrappers + return nil, fmt.Errorf("problem initializing node beacons: %w", err) + } + + // Set up tracer + n.tracer, err = trace.New(n.Config.TraceConfig) + if err != nil { + return nil, fmt.Errorf("couldn't initialize tracer: %w", err) + } + + if n.Config.TraceConfig.Enabled { + n.Config.ConsensusRouter = router.Trace(n.Config.ConsensusRouter, n.tracer) + } + + n.initMetrics() + + if err := n.initAPIServer(); err != nil { // Start the API Server + return nil, fmt.Errorf("couldn't initialize API server: %w", err) + } + + if err := n.initMetricsAPI(); err != nil { // Start the Metrics API + return nil, fmt.Errorf("couldn't initialize metrics API: %w", err) + } + + if err := n.initDatabase(); err != nil { // Set up the node's database + return nil, fmt.Errorf("problem initializing database: %w", err) + } + + if err := n.initKeystoreAPI(); err != nil { // Start the Keystore API + return nil, fmt.Errorf("couldn't initialize keystore API: %w", err) + } + + n.initSharedMemory() // Initialize shared memory + + // message.Creator is shared between networking, chainManager and the engine. + // It must be initiated before networking (initNetworking), chain manager (initChainManager) + // and the engine (initChains) but after the metrics (initMetricsAPI) + // message.Creator currently record metrics under network namespace + n.networkNamespace = "network" + n.msgCreator, err = message.NewCreator( + n.Log, + n.MetricsRegisterer, + n.networkNamespace, + n.Config.NetworkConfig.CompressionType, + n.Config.NetworkConfig.MaximumInboundMessageTimeout, + ) + if err != nil { + return nil, fmt.Errorf("problem initializing message creator: %w", err) + } + + n.vdrs = validators.NewManager() + if !n.Config.SybilProtectionEnabled { + n.vdrs = newOverriddenManager(constants.PrimaryNetworkID, n.vdrs) + } + if err := n.initResourceManager(n.MetricsRegisterer); err != nil { + return nil, fmt.Errorf("problem initializing resource manager: %w", err) + } + n.initCPUTargeter(&config.CPUTargeterConfig) + n.initDiskTargeter(&config.DiskTargeterConfig) + if err := n.initNetworking(); err != nil { // Set up networking layer. + return nil, fmt.Errorf("problem initializing networking: %w", err) + } + + n.initEventDispatchers() + + // Start the Health API + // Has to be initialized before chain manager + // [n.Net] must already be set + if err := n.initHealthAPI(); err != nil { + return nil, fmt.Errorf("couldn't initialize health API: %w", err) + } + if err := n.addDefaultVMAliases(); err != nil { + return nil, fmt.Errorf("couldn't initialize API aliases: %w", err) + } + if err := n.initChainManager(n.Config.AvaxAssetID); err != nil { // Set up the chain manager + return nil, fmt.Errorf("couldn't initialize chain manager: %w", err) + } + if err := n.initVMs(); err != nil { // Initialize the VM registry. + return nil, fmt.Errorf("couldn't initialize VM registry: %w", err) + } + if err := n.initAdminAPI(); err != nil { // Start the Admin API + return nil, fmt.Errorf("couldn't initialize admin API: %w", err) + } + if err := n.initInfoAPI(); err != nil { // Start the Info API + return nil, fmt.Errorf("couldn't initialize info API: %w", err) + } + if err := n.initIPCs(); err != nil { // Start the IPCs + return nil, fmt.Errorf("couldn't initialize IPCs: %w", err) + } + if err := n.initIPCAPI(); err != nil { // Start the IPC API + return nil, fmt.Errorf("couldn't initialize the IPC API: %w", err) + } + if err := n.initChainAliases(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize chain aliases: %w", err) + } + if err := n.initAPIAliases(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize API aliases: %w", err) + } + if err := n.initIndexer(); err != nil { + return nil, fmt.Errorf("couldn't initialize indexer: %w", err) + } + + n.health.Start(context.TODO(), n.Config.HealthCheckFreq) + n.initProfiler() + + // Start the Platform chain + if err := n.initChains(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize chains: %w", err) + } + return n, nil +} + // Node is an instance of an Avalanche node. type Node struct { Log logging.Logger @@ -1336,154 +1481,6 @@ func (n *Node) initDiskTargeter( ) } -// Initialize this node -func (n *Node) Initialize( - config *Config, - logger logging.Logger, - logFactory logging.Factory, -) error { - tlsCert := config.StakingTLSCert.Leaf - stakingCert := staking.CertificateFromX509(tlsCert) - if err := staking.ValidateCertificate(stakingCert); err != nil { - return fmt.Errorf("invalid staking certificate: %w", err) - } - - n.Log = logger - n.Config = config - n.ID = ids.NodeIDFromCert(stakingCert) - n.LogFactory = logFactory - n.DoneShuttingDown.Add(1) - - pop := signer.NewProofOfPossession(n.Config.StakingSigningKey) - n.Log.Info("initializing node", - zap.Stringer("version", version.CurrentApp), - zap.Stringer("nodeID", n.ID), - zap.Stringer("stakingKeyType", tlsCert.PublicKeyAlgorithm), - zap.Reflect("nodePOP", pop), - zap.Reflect("providedFlags", n.Config.ProvidedFlags), - zap.Reflect("config", n.Config), - ) - - var err error - n.VMFactoryLog, err = logFactory.Make("vm-factory") - if err != nil { - return fmt.Errorf("problem creating vm logger: %w", err) - } - - n.VMManager = vms.NewManager(n.VMFactoryLog, config.VMAliaser) - - if err := n.initBootstrappers(); err != nil { // Configure the bootstrappers - return fmt.Errorf("problem initializing node beacons: %w", err) - } - - // Set up tracer - n.tracer, err = trace.New(n.Config.TraceConfig) - if err != nil { - return fmt.Errorf("couldn't initialize tracer: %w", err) - } - - if n.Config.TraceConfig.Enabled { - n.Config.ConsensusRouter = router.Trace(n.Config.ConsensusRouter, n.tracer) - } - - n.initMetrics() - - if err := n.initAPIServer(); err != nil { // Start the API Server - return fmt.Errorf("couldn't initialize API server: %w", err) - } - - if err := n.initMetricsAPI(); err != nil { // Start the Metrics API - return fmt.Errorf("couldn't initialize metrics API: %w", err) - } - - if err := n.initDatabase(); err != nil { // Set up the node's database - return fmt.Errorf("problem initializing database: %w", err) - } - - if err := n.initKeystoreAPI(); err != nil { // Start the Keystore API - return fmt.Errorf("couldn't initialize keystore API: %w", err) - } - - n.initSharedMemory() // Initialize shared memory - - // message.Creator is shared between networking, chainManager and the engine. - // It must be initiated before networking (initNetworking), chain manager (initChainManager) - // and the engine (initChains) but after the metrics (initMetricsAPI) - // message.Creator currently record metrics under network namespace - n.networkNamespace = "network" - n.msgCreator, err = message.NewCreator( - n.Log, - n.MetricsRegisterer, - n.networkNamespace, - n.Config.NetworkConfig.CompressionType, - n.Config.NetworkConfig.MaximumInboundMessageTimeout, - ) - if err != nil { - return fmt.Errorf("problem initializing message creator: %w", err) - } - - n.vdrs = validators.NewManager() - if !n.Config.SybilProtectionEnabled { - n.vdrs = newOverriddenManager(constants.PrimaryNetworkID, n.vdrs) - } - if err := n.initResourceManager(n.MetricsRegisterer); err != nil { - return fmt.Errorf("problem initializing resource manager: %w", err) - } - n.initCPUTargeter(&config.CPUTargeterConfig) - n.initDiskTargeter(&config.DiskTargeterConfig) - if err := n.initNetworking(); err != nil { // Set up networking layer. - return fmt.Errorf("problem initializing networking: %w", err) - } - - n.initEventDispatchers() - - // Start the Health API - // Has to be initialized before chain manager - // [n.Net] must already be set - if err := n.initHealthAPI(); err != nil { - return fmt.Errorf("couldn't initialize health API: %w", err) - } - if err := n.addDefaultVMAliases(); err != nil { - return fmt.Errorf("couldn't initialize API aliases: %w", err) - } - if err := n.initChainManager(n.Config.AvaxAssetID); err != nil { // Set up the chain manager - return fmt.Errorf("couldn't initialize chain manager: %w", err) - } - if err := n.initVMs(); err != nil { // Initialize the VM registry. - return fmt.Errorf("couldn't initialize VM registry: %w", err) - } - if err := n.initAdminAPI(); err != nil { // Start the Admin API - return fmt.Errorf("couldn't initialize admin API: %w", err) - } - if err := n.initInfoAPI(); err != nil { // Start the Info API - return fmt.Errorf("couldn't initialize info API: %w", err) - } - if err := n.initIPCs(); err != nil { // Start the IPCs - return fmt.Errorf("couldn't initialize IPCs: %w", err) - } - if err := n.initIPCAPI(); err != nil { // Start the IPC API - return fmt.Errorf("couldn't initialize the IPC API: %w", err) - } - if err := n.initChainAliases(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize chain aliases: %w", err) - } - if err := n.initAPIAliases(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize API aliases: %w", err) - } - if err := n.initIndexer(); err != nil { - return fmt.Errorf("couldn't initialize indexer: %w", err) - } - - n.health.Start(context.TODO(), n.Config.HealthCheckFreq) - n.initProfiler() - - // Start the Platform chain - if err := n.initChains(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize chains: %w", err) - } - return nil -} - // Shutdown this node // May be called multiple times func (n *Node) Shutdown(exitCode int) {