github.com/prysmaticlabs/prysm@v1.4.4/cmd/validator/main.go (about)

     1  // Package main defines a validator client, a critical actor in Ethereum which manages
     2  // a keystore of private keys, connects to a beacon node to receive assignments,
     3  // and submits blocks/attestations as needed.
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"runtime"
    11  	runtimeDebug "runtime/debug"
    12  
    13  	joonix "github.com/joonix/log"
    14  	accountcommands "github.com/prysmaticlabs/prysm/cmd/validator/accounts"
    15  	dbcommands "github.com/prysmaticlabs/prysm/cmd/validator/db"
    16  	"github.com/prysmaticlabs/prysm/cmd/validator/flags"
    17  	slashingprotectioncommands "github.com/prysmaticlabs/prysm/cmd/validator/slashing-protection"
    18  	walletcommands "github.com/prysmaticlabs/prysm/cmd/validator/wallet"
    19  	"github.com/prysmaticlabs/prysm/shared/cmd"
    20  	"github.com/prysmaticlabs/prysm/shared/debug"
    21  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    22  	"github.com/prysmaticlabs/prysm/shared/fileutil"
    23  	"github.com/prysmaticlabs/prysm/shared/journald"
    24  	"github.com/prysmaticlabs/prysm/shared/logutil"
    25  	_ "github.com/prysmaticlabs/prysm/shared/maxprocs"
    26  	"github.com/prysmaticlabs/prysm/shared/tos"
    27  	"github.com/prysmaticlabs/prysm/shared/version"
    28  	"github.com/prysmaticlabs/prysm/validator/node"
    29  	"github.com/sirupsen/logrus"
    30  	"github.com/urfave/cli/v2"
    31  	prefixed "github.com/x-cray/logrus-prefixed-formatter"
    32  )
    33  
    34  func startNode(ctx *cli.Context) error {
    35  	// verify if ToS accepted
    36  	if err := tos.VerifyTosAcceptedOrPrompt(ctx); err != nil {
    37  		return err
    38  	}
    39  
    40  	validatorClient, err := node.NewValidatorClient(ctx)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	validatorClient.Start()
    45  	return nil
    46  }
    47  
    48  var appFlags = []cli.Flag{
    49  	flags.BeaconRPCProviderFlag,
    50  	flags.BeaconRPCGatewayProviderFlag,
    51  	flags.CertFlag,
    52  	flags.GraffitiFlag,
    53  	flags.DisablePenaltyRewardLogFlag,
    54  	flags.InteropStartIndex,
    55  	flags.InteropNumValidators,
    56  	flags.EnableRPCFlag,
    57  	flags.RPCHost,
    58  	flags.RPCPort,
    59  	flags.GRPCGatewayPort,
    60  	flags.GRPCGatewayHost,
    61  	flags.GrpcRetriesFlag,
    62  	flags.GrpcRetryDelayFlag,
    63  	flags.GrpcHeadersFlag,
    64  	flags.GPRCGatewayCorsDomain,
    65  	flags.DisableAccountMetricsFlag,
    66  	cmd.MonitoringHostFlag,
    67  	flags.MonitoringPortFlag,
    68  	cmd.DisableMonitoringFlag,
    69  	flags.SlasherRPCProviderFlag,
    70  	flags.SlasherCertFlag,
    71  	flags.WalletPasswordFileFlag,
    72  	flags.WalletDirFlag,
    73  	flags.EnableWebFlag,
    74  	flags.GraffitiFileFlag,
    75  	flags.EnableDutyCountDown,
    76  	cmd.BackupWebhookOutputDir,
    77  	cmd.EnableBackupWebhookFlag,
    78  	cmd.MinimalConfigFlag,
    79  	cmd.E2EConfigFlag,
    80  	cmd.VerbosityFlag,
    81  	cmd.DataDirFlag,
    82  	cmd.ClearDB,
    83  	cmd.ForceClearDB,
    84  	cmd.EnableTracingFlag,
    85  	cmd.TracingProcessNameFlag,
    86  	cmd.TracingEndpointFlag,
    87  	cmd.TraceSampleFractionFlag,
    88  	cmd.LogFormat,
    89  	cmd.LogFileName,
    90  	cmd.ConfigFileFlag,
    91  	cmd.ChainConfigFileFlag,
    92  	cmd.GrpcMaxCallRecvMsgSizeFlag,
    93  	cmd.BoltMMapInitialSizeFlag,
    94  	debug.PProfFlag,
    95  	debug.PProfAddrFlag,
    96  	debug.PProfPortFlag,
    97  	debug.MemProfileRateFlag,
    98  	debug.CPUProfileFlag,
    99  	debug.TraceFlag,
   100  	debug.BlockProfileRateFlag,
   101  	debug.MutexProfileFractionFlag,
   102  	cmd.AcceptTosFlag,
   103  }
   104  
   105  func init() {
   106  	appFlags = cmd.WrapFlags(append(appFlags, featureconfig.ValidatorFlags...))
   107  }
   108  
   109  func main() {
   110  	app := cli.App{}
   111  	app.Name = "validator"
   112  	app.Usage = `launches an Ethereum validator client that interacts with a beacon chain, starts proposer and attester services, p2p connections, and more`
   113  	app.Version = version.Version()
   114  	app.Action = startNode
   115  	app.Commands = []*cli.Command{
   116  		walletcommands.Commands,
   117  		accountcommands.Commands,
   118  		slashingprotectioncommands.Commands,
   119  		dbcommands.Commands,
   120  	}
   121  
   122  	app.Flags = appFlags
   123  
   124  	app.Before = func(ctx *cli.Context) error {
   125  		// Load flags from config file, if specified.
   126  		if err := cmd.LoadFlagsFromConfig(ctx, app.Flags); err != nil {
   127  			return err
   128  		}
   129  
   130  		format := ctx.String(cmd.LogFormat.Name)
   131  		switch format {
   132  		case "text":
   133  			formatter := new(prefixed.TextFormatter)
   134  			formatter.TimestampFormat = "2006-01-02 15:04:05"
   135  			formatter.FullTimestamp = true
   136  			// If persistent log files are written - we disable the log messages coloring because
   137  			// the colors are ANSI codes and seen as Gibberish in the log files.
   138  			formatter.DisableColors = ctx.String(cmd.LogFileName.Name) != ""
   139  			logrus.SetFormatter(formatter)
   140  		case "fluentd":
   141  			f := joonix.NewFormatter()
   142  			if err := joonix.DisableTimestampFormat(f); err != nil {
   143  				panic(err)
   144  			}
   145  			logrus.SetFormatter(f)
   146  		case "json":
   147  			logrus.SetFormatter(&logrus.JSONFormatter{})
   148  		case "journald":
   149  			if err := journald.Enable(); err != nil {
   150  				return err
   151  			}
   152  		default:
   153  			return fmt.Errorf("unknown log format %s", format)
   154  		}
   155  
   156  		logFileName := ctx.String(cmd.LogFileName.Name)
   157  		if logFileName != "" {
   158  			if err := logutil.ConfigurePersistentLogging(logFileName); err != nil {
   159  				log.WithError(err).Error("Failed to configuring logging to disk.")
   160  			}
   161  		}
   162  
   163  		// Fix data dir for Windows users.
   164  		outdatedDataDir := filepath.Join(fileutil.HomeDir(), "AppData", "Roaming", "Eth2Validators")
   165  		currentDataDir := flags.DefaultValidatorDir()
   166  		if err := cmd.FixDefaultDataDir(outdatedDataDir, currentDataDir); err != nil {
   167  			log.WithError(err).Error("Cannot update data directory")
   168  		}
   169  
   170  		runtime.GOMAXPROCS(runtime.NumCPU())
   171  		if err := debug.Setup(ctx); err != nil {
   172  			return err
   173  		}
   174  		return cmd.ValidateNoArgs(ctx)
   175  	}
   176  
   177  	app.After = func(ctx *cli.Context) error {
   178  		debug.Exit(ctx)
   179  		return nil
   180  	}
   181  
   182  	defer func() {
   183  		if x := recover(); x != nil {
   184  			log.Errorf("Runtime panic: %v\n%v", x, string(runtimeDebug.Stack()))
   185  			panic(x)
   186  		}
   187  	}()
   188  
   189  	if err := app.Run(os.Args); err != nil {
   190  		log.Error(err.Error())
   191  	}
   192  }