code.vegaprotocol.io/vega@v0.79.0/cmd/data-node/commands/start/node.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package start
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  	"net/http"
    23  	"os"
    24  	"os/signal"
    25  	"syscall"
    26  
    27  	"code.vegaprotocol.io/vega/datanode/admin"
    28  	"code.vegaprotocol.io/vega/datanode/api"
    29  	"code.vegaprotocol.io/vega/datanode/broker"
    30  	"code.vegaprotocol.io/vega/datanode/config"
    31  	"code.vegaprotocol.io/vega/datanode/gateway/server"
    32  	"code.vegaprotocol.io/vega/datanode/metrics"
    33  	"code.vegaprotocol.io/vega/datanode/networkhistory"
    34  	"code.vegaprotocol.io/vega/datanode/networkhistory/snapshot"
    35  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    36  	"code.vegaprotocol.io/vega/libs/pprof"
    37  	"code.vegaprotocol.io/vega/libs/subscribers"
    38  	"code.vegaprotocol.io/vega/logging"
    39  	"code.vegaprotocol.io/vega/paths"
    40  
    41  	embeddedpostgres "github.com/fergusstrange/embedded-postgres"
    42  	"golang.org/x/sync/errgroup"
    43  )
    44  
    45  // NodeCommand use to implement 'node' command.
    46  type NodeCommand struct {
    47  	SQLSubscribers
    48  	ctx    context.Context
    49  	cancel context.CancelFunc
    50  
    51  	embeddedPostgres              *embeddedpostgres.EmbeddedPostgres
    52  	transactionalConnectionSource *sqlstore.ConnectionSource
    53  
    54  	networkHistoryService *networkhistory.Service
    55  	snapshotService       *snapshot.Service
    56  
    57  	vegaCoreServiceClient api.CoreServiceClient
    58  
    59  	broker    *broker.Broker
    60  	sqlBroker broker.SQLStoreEventBroker
    61  
    62  	eventService *subscribers.Service
    63  
    64  	pproffhandlr  *pprof.Pprofhandler
    65  	Log           *logging.Logger
    66  	vegaPaths     paths.Paths
    67  	configWatcher *config.Watcher
    68  	conf          config.Config
    69  
    70  	Version     string
    71  	VersionHash string
    72  }
    73  
    74  func (l *NodeCommand) Run(ctx context.Context, cfgwatchr *config.Watcher, vegaPaths paths.Paths, args []string) error {
    75  	l.configWatcher = cfgwatchr
    76  
    77  	l.conf = cfgwatchr.Get()
    78  	l.vegaPaths = vegaPaths
    79  	if l.cancel != nil {
    80  		l.cancel()
    81  	}
    82  	l.ctx, l.cancel = context.WithCancel(ctx)
    83  
    84  	stages := []func([]string) error{
    85  		l.persistentPre,
    86  		l.preRun,
    87  		l.runNode,
    88  		l.postRun,
    89  		l.persistentPost,
    90  	}
    91  	for _, fn := range stages {
    92  		if err := fn(args); err != nil {
    93  			return err
    94  		}
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  // Stop is for graceful shutdown.
   101  func (l *NodeCommand) Stop() {
   102  	l.cancel()
   103  }
   104  
   105  // runNode is the entry of node command.
   106  func (l *NodeCommand) runNode([]string) error {
   107  	nodeLog := l.Log.Named("start.runNode")
   108  	var eg *errgroup.Group
   109  	eg, l.ctx = errgroup.WithContext(l.ctx)
   110  
   111  	// gRPC server
   112  	grpcServer := l.createGRPCServer(l.conf.API)
   113  
   114  	// Admin server
   115  	adminServer := admin.NewServer(l.Log, l.conf.Admin, l.vegaPaths, admin.NewNetworkHistoryAdminService(l.networkHistoryService))
   116  
   117  	// watch configs
   118  	l.configWatcher.OnConfigUpdate(
   119  		func(cfg config.Config) {
   120  			grpcServer.ReloadConf(cfg.API)
   121  			adminServer.ReloadConf(cfg.Admin)
   122  		},
   123  	)
   124  
   125  	// start the grpc server
   126  	eg.Go(func() error { return grpcServer.Start(l.ctx, nil) })
   127  
   128  	// start the admin server
   129  	eg.Go(func() error {
   130  		if err := adminServer.Start(l.ctx); err != nil && err != http.ErrServerClosed {
   131  			return err
   132  		}
   133  		return nil
   134  	})
   135  
   136  	// start gateway
   137  	if l.conf.GatewayEnabled {
   138  		gty := server.New(l.conf.Gateway, l.Log, l.vegaPaths)
   139  		eg.Go(func() error { return gty.Start(l.ctx) })
   140  	}
   141  
   142  	eg.Go(func() error {
   143  		return l.broker.Receive(l.ctx)
   144  	})
   145  
   146  	eg.Go(func() error {
   147  		defer func() {
   148  			if l.conf.NetworkHistory.Enabled {
   149  				l.networkHistoryService.Stop()
   150  			}
   151  		}()
   152  
   153  		return l.sqlBroker.Receive(l.ctx)
   154  	})
   155  
   156  	// waitSig will wait for a sigterm or sigint interrupt.
   157  	eg.Go(func() error {
   158  		gracefulStop := make(chan os.Signal, 1)
   159  		signal.Notify(gracefulStop, syscall.SIGTERM, syscall.SIGINT)
   160  
   161  		select {
   162  		case sig := <-gracefulStop:
   163  			nodeLog.Info("Caught signal", logging.String("name", fmt.Sprintf("%+v", sig)))
   164  			l.cancel()
   165  		case <-l.ctx.Done():
   166  			return l.ctx.Err()
   167  		}
   168  		return nil
   169  	})
   170  
   171  	metrics.Start(l.conf.Metrics)
   172  
   173  	nodeLog.Info("Vega data node startup complete")
   174  
   175  	if err := eg.Wait(); err != nil && !errors.Is(err, context.Canceled) {
   176  		nodeLog.Error("Vega data node stopped with error", logging.Error(err))
   177  		return fmt.Errorf("vega data node stopped with error: %w", err)
   178  	}
   179  
   180  	return nil
   181  }
   182  
   183  func (l *NodeCommand) createGRPCServer(config api.Config) *api.GRPCServer {
   184  	grpcServer := api.NewGRPCServer(
   185  		l.Log,
   186  		config,
   187  		l.vegaCoreServiceClient,
   188  		l.eventService,
   189  		l.orderService,
   190  		l.networkLimitsService,
   191  		l.marketDataService,
   192  		l.tradeService,
   193  		l.assetService,
   194  		l.accountService,
   195  		l.rewardService,
   196  		l.marketsService,
   197  		l.delegationService,
   198  		l.epochService,
   199  		l.depositService,
   200  		l.withdrawalService,
   201  		l.governanceService,
   202  		l.riskFactorService,
   203  		l.riskService,
   204  		l.networkParameterService,
   205  		l.blockService,
   206  		l.checkpointService,
   207  		l.partyService,
   208  		l.candleService,
   209  		l.oracleSpecService,
   210  		l.oracleDataService,
   211  		l.liquidityProvisionService,
   212  		l.positionService,
   213  		l.transferService,
   214  		l.stakeLinkingService,
   215  		l.notaryService,
   216  		l.multiSigService,
   217  		l.keyRotationsService,
   218  		l.ethereumKeyRotationsService,
   219  		l.nodeService,
   220  		l.marketDepthService,
   221  		l.ledgerService,
   222  		l.protocolUpgradeService,
   223  		l.networkHistoryService,
   224  		l.coreSnapshotService,
   225  		l.stopOrderService,
   226  		l.fundingPeriodService,
   227  		l.partyActivityStreakService,
   228  		l.referralProgramService,
   229  		l.referralSetsService,
   230  		l.teamsService,
   231  		l.vestingStatsService,
   232  		l.feesStatsService,
   233  		l.fundingPaymentService,
   234  		l.volumeDiscountStatsService,
   235  		l.volumeDiscountProgramService,
   236  		l.paidLiquidityFeesStatsService,
   237  		l.partyLockedBalancesService,
   238  		l.partyVestingBalancesService,
   239  		l.transactionResultsService,
   240  		l.gamesService,
   241  		l.marginModesService,
   242  		l.timeWeightedNotionalPositionService,
   243  		l.gameScoreService,
   244  		l.ammPoolsService,
   245  		l.volumeRebateStatsService,
   246  		l.volumeRebateProgramService,
   247  	)
   248  	return grpcServer
   249  }