Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var GenerateDocCmd = &cobra.Command{ Use: "doc", Short: "Generate CLI documentation for the node", Run: func(cmd *cobra.Command, args []string) { var cfg config t := reflect.TypeOf(cfg) var docs []ArgumentDoc getAllFields(t, nil, nil, &docs) tbl := table.New(os.Stdout) tbl.SetHeaders("YAML", "ENV", "Default", "Description") for _, doc := range docs { yamlName := strings.Join(doc.YAMLPath, ".") tbl.AddRow(yamlName, doc.EnvName, doc.Default, doc.Description) } tbl.Render() }, }
View Source
var StartNodeCmd = &cobra.Command{ Use: "start-node", Short: "Starts an instance of SSV node", Run: func(cmd *cobra.Command, args []string) { commons.SetBuildData(cmd.Parent().Short, cmd.Parent().Version) logger, err := setupGlobal() if err != nil { log.Fatal("could not create logger", err) } defer logging.CapturePanic(logger) logger.Info(fmt.Sprintf("starting %v", commons.GetBuildData())) metricsReporter := metricsreporter.New( metricsreporter.WithLogger(logger), ) networkConfig, err := setupSSVNetwork(logger) if err != nil { logger.Fatal("could not setup network", zap.Error(err)) } cfg.DBOptions.Ctx = cmd.Context() db, err := setupDB(logger, networkConfig.Beacon.GetNetwork()) if err != nil { logger.Fatal("could not setup db", zap.Error(err)) } var operatorPrivKey keys.OperatorPrivateKey var operatorPrivKeyText string if cfg.KeyStore.PrivateKeyFile != "" { encryptedJSON, err := os.ReadFile(cfg.KeyStore.PrivateKeyFile) if err != nil { logger.Fatal("could not read PEM file", zap.Error(err)) } keyStorePassword, err := os.ReadFile(cfg.KeyStore.PasswordFile) if err != nil { logger.Fatal("could not read password file", zap.Error(err)) } decryptedKeystore, err := keystore.DecryptKeystore(encryptedJSON, string(keyStorePassword)) if err != nil { logger.Fatal("could not decrypt operator private key keystore", zap.Error(err)) } operatorPrivKey, err = keys.PrivateKeyFromBytes(decryptedKeystore) if err != nil { logger.Fatal("could not extract operator private key from file", zap.Error(err)) } operatorPrivKeyText = base64.StdEncoding.EncodeToString(decryptedKeystore) } else { operatorPrivKey, err = keys.PrivateKeyFromString(cfg.OperatorPrivateKey) if err != nil { logger.Fatal("could not decode operator private key", zap.Error(err)) } operatorPrivKeyText = cfg.OperatorPrivateKey } cfg.P2pNetworkConfig.OperatorSigner = operatorPrivKey nodeStorage, operatorData := setupOperatorStorage(logger, db, operatorPrivKey, operatorPrivKeyText) operatorDataStore := operatordatastore.New(operatorData) usingLocalEvents := len(cfg.LocalEventsPath) != 0 verifyConfig(logger, nodeStorage, networkConfig.Name, usingLocalEvents) ekmHashedKey, err := operatorPrivKey.EKMHash() if err != nil { logger.Fatal("could not get operator private key hash", zap.Error(err)) } keyManager, err := ekm.NewETHKeyManagerSigner(logger, db, networkConfig, ekmHashedKey) if err != nil { logger.Fatal("could not create new eth-key-manager signer", zap.Error(err)) } cfg.P2pNetworkConfig.Ctx = cmd.Context() permissioned := func() bool { currentEpoch := networkConfig.Beacon.EstimatedCurrentEpoch() return currentEpoch < networkConfig.PermissionlessActivationEpoch } slotTickerProvider := func() slotticker.SlotTicker { return slotticker.New(logger, slotticker.Config{ SlotDuration: networkConfig.SlotDurationSec(), GenesisTime: networkConfig.GetGenesisTime(), }) } cfg.ConsensusClient.Context = cmd.Context() cfg.ConsensusClient.Graffiti = []byte(cfg.Graffiti) cfg.ConsensusClient.GasLimit = spectypes.DefaultGasLimit cfg.ConsensusClient.Network = networkConfig.Beacon.GetNetwork() consensusClient := setupConsensusClient(logger, operatorDataStore, slotTickerProvider) executionClient, err := executionclient.New( cmd.Context(), cfg.ExecutionClient.Addr, ethcommon.HexToAddress(networkConfig.RegistryContractAddr), executionclient.WithLogger(logger), executionclient.WithMetrics(metricsReporter), executionclient.WithFollowDistance(executionclient.DefaultFollowDistance), executionclient.WithConnectionTimeout(cfg.ExecutionClient.ConnectionTimeout), executionclient.WithReconnectionInitialInterval(executionclient.DefaultReconnectionInitialInterval), executionclient.WithReconnectionMaxInterval(executionclient.DefaultReconnectionMaxInterval), ) if err != nil { logger.Fatal("could not connect to execution client", zap.Error(err)) } cfg.P2pNetworkConfig.Permissioned = permissioned cfg.P2pNetworkConfig.NodeStorage = nodeStorage cfg.P2pNetworkConfig.OperatorPubKeyHash = format.OperatorID(operatorData.PublicKey) cfg.P2pNetworkConfig.OperatorDataStore = operatorDataStore cfg.P2pNetworkConfig.FullNode = cfg.SSVOptions.ValidatorOptions.FullNode cfg.P2pNetworkConfig.Network = networkConfig validatorsMap := validatorsmap.New(cmd.Context()) dutyStore := dutystore.New() cfg.SSVOptions.DutyStore = dutyStore messageValidator := validation.NewMessageValidator( networkConfig, validation.WithNodeStorage(nodeStorage), validation.WithLogger(logger), validation.WithMetrics(metricsReporter), validation.WithDutyStore(dutyStore), validation.WithOwnOperatorID(operatorDataStore), ) cfg.P2pNetworkConfig.Metrics = metricsReporter cfg.P2pNetworkConfig.MessageValidator = messageValidator cfg.SSVOptions.ValidatorOptions.MessageValidator = messageValidator p2pNetwork := setupP2P(logger, db, metricsReporter) cfg.SSVOptions.Context = cmd.Context() cfg.SSVOptions.DB = db cfg.SSVOptions.BeaconNode = consensusClient cfg.SSVOptions.ExecutionClient = executionClient cfg.SSVOptions.Network = networkConfig cfg.SSVOptions.P2PNetwork = p2pNetwork cfg.SSVOptions.ValidatorOptions.BeaconNetwork = networkConfig.Beacon.GetNetwork() cfg.SSVOptions.ValidatorOptions.Context = cmd.Context() cfg.SSVOptions.ValidatorOptions.DB = db cfg.SSVOptions.ValidatorOptions.Network = p2pNetwork cfg.SSVOptions.ValidatorOptions.Beacon = consensusClient cfg.SSVOptions.ValidatorOptions.KeyManager = keyManager cfg.SSVOptions.ValidatorOptions.ValidatorsMap = validatorsMap cfg.SSVOptions.ValidatorOptions.OperatorDataStore = operatorDataStore cfg.SSVOptions.ValidatorOptions.RegistryStorage = nodeStorage cfg.SSVOptions.ValidatorOptions.RecipientsStorage = nodeStorage cfg.SSVOptions.ValidatorOptions.GasLimit = cfg.ConsensusClient.GasLimit if cfg.WsAPIPort != 0 { ws := exporterapi.NewWsServer(cmd.Context(), nil, http.NewServeMux(), cfg.WithPing) cfg.SSVOptions.WS = ws cfg.SSVOptions.WsAPIPort = cfg.WsAPIPort cfg.SSVOptions.ValidatorOptions.NewDecidedHandler = decided.NewStreamPublisher(logger, ws) } cfg.SSVOptions.ValidatorOptions.DutyRoles = []spectypes.BeaconRole{spectypes.BNRoleAttester} storageRoles := []spectypes.BeaconRole{ spectypes.BNRoleAttester, spectypes.BNRoleProposer, spectypes.BNRoleAggregator, spectypes.BNRoleSyncCommittee, spectypes.BNRoleSyncCommitteeContribution, spectypes.BNRoleValidatorRegistration, spectypes.BNRoleVoluntaryExit, } storageMap := ibftstorage.NewStores() for _, storageRole := range storageRoles { storageMap.Add(storageRole, ibftstorage.New(cfg.SSVOptions.ValidatorOptions.DB, storageRole.String())) } cfg.SSVOptions.ValidatorOptions.StorageMap = storageMap cfg.SSVOptions.ValidatorOptions.Metrics = metricsReporter cfg.SSVOptions.ValidatorOptions.Graffiti = []byte(cfg.Graffiti) cfg.SSVOptions.Metrics = metricsReporter validatorCtrl := validator.NewController(logger, cfg.SSVOptions.ValidatorOptions) cfg.SSVOptions.ValidatorController = validatorCtrl operatorNode = operator.New(logger, cfg.SSVOptions, slotTickerProvider) if cfg.MetricsAPIPort > 0 { go startMetricsHandler(cmd.Context(), logger, db, metricsReporter, cfg.MetricsAPIPort, cfg.EnableProfile) } nodeProber := nodeprobe.NewProber( logger, func() { logger.Fatal("ethereum node(s) are either out of sync or down. Ensure the nodes are healthy to resume.") }, map[string]nodeprobe.Node{ "execution client": executionClient, "consensus client": consensusClient.(nodeprobe.Node), }, ) nodeProber.Start(cmd.Context()) nodeProber.Wait() logger.Info("ethereum node(s) are healthy") metricsReporter.SSVNodeHealthy() eventSyncer := setupEventHandling( cmd.Context(), logger, executionClient, validatorCtrl, metricsReporter, networkConfig, nodeStorage, operatorDataStore, operatorPrivKey, ) nodeProber.AddNode("event syncer", eventSyncer) cfg.P2pNetworkConfig.GetValidatorStats = func() (uint64, uint64, uint64, error) { return validatorCtrl.GetValidatorStats() } if err := p2pNetwork.Setup(logger); err != nil { logger.Fatal("failed to setup network", zap.Error(err)) } if err := p2pNetwork.Start(logger); err != nil { logger.Fatal("failed to start network", zap.Error(err)) } if cfg.SSVAPIPort > 0 { apiServer := apiserver.New( logger, fmt.Sprintf(":%d", cfg.SSVAPIPort), &handlers.Node{ ListenAddresses: []string{fmt.Sprintf("tcp://%s:%d", cfg.P2pNetworkConfig.HostAddress, cfg.P2pNetworkConfig.TCPPort), fmt.Sprintf("udp://%s:%d", cfg.P2pNetworkConfig.HostAddress, cfg.P2pNetworkConfig.UDPPort)}, PeersIndex: p2pNetwork.(p2pv1.PeersIndexProvider).PeersIndex(), Network: p2pNetwork.(p2pv1.HostProvider).Host().Network(), TopicIndex: p2pNetwork.(handlers.TopicIndex), NodeProber: nodeProber, }, &handlers.Validators{ Shares: nodeStorage.Shares(), }, ) go func() { err := apiServer.Run() if err != nil { logger.Fatal("failed to start API server", zap.Error(err)) } }() } if err := operatorNode.Start(logger); err != nil { logger.Fatal("failed to start SSV node", zap.Error(err)) } }, }
StartNodeCmd is the command to start SSV node
Functions ¶
This section is empty.
Types ¶
type ArgumentDoc ¶ added in v1.1.0
Click to show internal directories.
Click to hide internal directories.