2020-04-29 21:32:39 +00:00
// Package node is the main process which handles the lifecycle of
// the runtime services in a validator client process, gracefully shutting
// everything down upon close.
2018-06-02 22:29:35 +00:00
package node
import (
2018-06-03 23:24:31 +00:00
"fmt"
2020-02-03 17:13:58 +00:00
"io/ioutil"
2018-06-11 22:21:24 +00:00
"os"
"os/signal"
2020-09-08 16:42:06 +00:00
"path/filepath"
2020-01-24 17:21:31 +00:00
"strings"
2018-06-04 20:00:47 +00:00
"sync"
2018-06-11 22:21:24 +00:00
"syscall"
2018-06-02 22:29:35 +00:00
2019-08-02 02:27:38 +00:00
"github.com/pkg/errors"
2018-07-20 21:31:26 +00:00
"github.com/prysmaticlabs/prysm/shared"
"github.com/prysmaticlabs/prysm/shared/cmd"
"github.com/prysmaticlabs/prysm/shared/debug"
2020-09-03 15:11:17 +00:00
"github.com/prysmaticlabs/prysm/shared/event"
2019-03-21 02:57:25 +00:00
"github.com/prysmaticlabs/prysm/shared/featureconfig"
2020-09-08 16:42:06 +00:00
"github.com/prysmaticlabs/prysm/shared/fileutil"
2020-05-05 22:19:27 +00:00
"github.com/prysmaticlabs/prysm/shared/params"
2020-10-02 06:45:34 +00:00
"github.com/prysmaticlabs/prysm/shared/prereq"
2019-01-13 07:01:11 +00:00
"github.com/prysmaticlabs/prysm/shared/prometheus"
2019-02-28 03:55:47 +00:00
"github.com/prysmaticlabs/prysm/shared/tracing"
2019-01-10 04:19:33 +00:00
"github.com/prysmaticlabs/prysm/shared/version"
2020-09-17 01:34:42 +00:00
"github.com/prysmaticlabs/prysm/validator/accounts/v2/wallet"
2020-07-02 17:50:05 +00:00
"github.com/prysmaticlabs/prysm/validator/client"
2020-06-27 02:37:43 +00:00
"github.com/prysmaticlabs/prysm/validator/db/kv"
2020-01-09 04:49:32 +00:00
"github.com/prysmaticlabs/prysm/validator/flags"
2020-07-08 05:01:09 +00:00
v1 "github.com/prysmaticlabs/prysm/validator/keymanager/v1"
v2 "github.com/prysmaticlabs/prysm/validator/keymanager/v2"
2020-08-25 01:37:25 +00:00
"github.com/prysmaticlabs/prysm/validator/keymanager/v2/direct"
2020-08-12 23:33:15 +00:00
"github.com/prysmaticlabs/prysm/validator/rpc"
2020-08-14 02:49:57 +00:00
"github.com/prysmaticlabs/prysm/validator/rpc/gateway"
2020-05-20 15:23:22 +00:00
slashing_protection "github.com/prysmaticlabs/prysm/validator/slashing-protection"
2020-10-09 14:58:30 +00:00
"github.com/prysmaticlabs/prysm/validator/web"
2020-07-08 05:01:09 +00:00
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
2018-06-02 22:29:35 +00:00
)
2018-07-21 17:51:18 +00:00
var log = logrus . WithField ( "prefix" , "node" )
2020-07-08 05:01:09 +00:00
// ValidatorClient defines an instance of an eth2 validator that manages
// the entire lifecycle of services attached to it participating in eth2.
2018-10-18 17:33:38 +00:00
type ValidatorClient struct {
2020-09-03 15:11:17 +00:00
cliCtx * cli . Context
db * kv . Store
services * shared . ServiceRegistry // Lifecycle and service store.
lock sync . RWMutex
2020-09-17 01:34:42 +00:00
wallet * wallet . Wallet
2020-09-03 15:11:17 +00:00
walletInitialized * event . Feed
stop chan struct { } // Channel to wait for termination notifications.
2018-09-26 03:27:52 +00:00
}
2020-07-08 05:01:09 +00:00
// NewValidatorClient creates a new, Prysm validator client.
2020-05-07 15:14:08 +00:00
func NewValidatorClient ( cliCtx * cli . Context ) ( * ValidatorClient , error ) {
2019-02-28 03:55:47 +00:00
if err := tracing . Setup (
"validator" , // service name
2020-05-07 15:14:08 +00:00
cliCtx . String ( cmd . TracingProcessNameFlag . Name ) ,
cliCtx . String ( cmd . TracingEndpointFlag . Name ) ,
cliCtx . Float64 ( cmd . TraceSampleFractionFlag . Name ) ,
cliCtx . Bool ( cmd . EnableTracingFlag . Name ) ,
2019-02-28 03:55:47 +00:00
) ; err != nil {
return nil , err
}
2019-09-26 18:23:25 +00:00
2020-05-07 15:14:08 +00:00
verbosity := cliCtx . String ( cmd . VerbosityFlag . Name )
2019-09-26 18:23:25 +00:00
level , err := logrus . ParseLevel ( verbosity )
if err != nil {
return nil , err
}
logrus . SetLevel ( level )
2020-10-02 06:45:34 +00:00
// Warn if user's platform is not supported
prereq . WarnIfNotSupported ( cliCtx . Context )
2018-07-14 02:15:37 +00:00
registry := shared . NewServiceRegistry ( )
2018-10-18 17:33:38 +00:00
ValidatorClient := & ValidatorClient {
2020-09-03 15:11:17 +00:00
cliCtx : cliCtx ,
services : registry ,
walletInitialized : new ( event . Feed ) ,
stop : make ( chan struct { } ) ,
2018-06-06 15:04:20 +00:00
}
2018-09-27 21:46:07 +00:00
2020-08-01 00:46:55 +00:00
featureconfig . ConfigureValidator ( cliCtx )
cmd . ConfigureValidator ( cliCtx )
2020-05-07 15:14:08 +00:00
if cliCtx . IsSet ( cmd . ChainConfigFileFlag . Name ) {
chainConfigFileName := cliCtx . String ( cmd . ChainConfigFileFlag . Name )
2020-05-05 22:19:27 +00:00
params . LoadChainConfigFile ( chainConfigFileName )
}
2020-09-03 15:11:17 +00:00
// If the --web flag is enabled to administer the validator
// client via a web portal, we start the validator client in a different way.
if cliCtx . IsSet ( flags . EnableWebFlag . Name ) {
log . Info ( "Enabling web portal to manage the validator client" )
if err := ValidatorClient . initializeForWeb ( cliCtx ) ; err != nil {
return nil , err
}
return ValidatorClient , nil
}
if err := ValidatorClient . initializeFromCLI ( cliCtx ) ; err != nil {
return nil , err
}
return ValidatorClient , nil
}
// Start every service in the validator client.
func ( s * ValidatorClient ) Start ( ) {
s . lock . Lock ( )
log . WithFields ( logrus . Fields {
"version" : version . GetVersion ( ) ,
} ) . Info ( "Starting validator node" )
s . services . StartAll ( )
stop := s . stop
s . lock . Unlock ( )
go func ( ) {
sigc := make ( chan os . Signal , 1 )
signal . Notify ( sigc , syscall . SIGINT , syscall . SIGTERM )
defer signal . Stop ( sigc )
<- sigc
log . Info ( "Got interrupt, shutting down..." )
debug . Exit ( s . cliCtx ) // Ensure trace and CPU profile data are flushed.
go s . Close ( )
for i := 10 ; i > 0 ; i -- {
<- sigc
if i > 1 {
log . WithField ( "times" , i - 1 ) . Info ( "Already shutting down, interrupt more to panic." )
}
}
panic ( "Panic closing the validator client" )
} ( )
// Wait for stop channel to be closed.
<- stop
}
// Close handles graceful shutdown of the system.
func ( s * ValidatorClient ) Close ( ) {
s . lock . Lock ( )
defer s . lock . Unlock ( )
s . services . StopAll ( )
log . Info ( "Stopping Prysm validator" )
if ! s . cliCtx . IsSet ( flags . InteropNumValidators . Name ) {
if err := s . wallet . UnlockWalletConfigFile ( ) ; err != nil {
log . WithError ( err ) . Errorf ( "Failed to unlock wallet config file." )
}
}
close ( s . stop )
}
func ( s * ValidatorClient ) initializeFromCLI ( cliCtx * cli . Context ) error {
2020-07-24 21:36:28 +00:00
var keyManagerV1 v1 . KeyManager
2020-07-08 05:01:09 +00:00
var keyManagerV2 v2 . IKeymanager
2020-09-03 15:11:17 +00:00
var err error
2020-09-08 16:42:06 +00:00
var accountsDir string
2020-07-08 05:01:09 +00:00
if featureconfig . Get ( ) . EnableAccountsV2 {
2020-08-25 01:37:25 +00:00
if cliCtx . IsSet ( flags . InteropNumValidators . Name ) {
numValidatorKeys := cliCtx . Uint64 ( flags . InteropNumValidators . Name )
offset := cliCtx . Uint64 ( flags . InteropStartIndex . Name )
2020-08-31 19:46:45 +00:00
keyManagerV2 , err = direct . NewInteropKeymanager ( cliCtx . Context , offset , numValidatorKeys )
2020-08-25 01:37:25 +00:00
if err != nil {
2020-09-03 15:11:17 +00:00
return errors . Wrap ( err , "could not generate interop keys" )
2020-08-25 01:37:25 +00:00
}
2020-09-08 16:42:06 +00:00
accountsDir = cliCtx . String ( flags . KeystorePathFlag . Name )
2020-08-25 01:37:25 +00:00
} else {
// Read the wallet from the specified path.
2020-09-17 01:34:42 +00:00
w , err := wallet . OpenWalletOrElseCli ( cliCtx , func ( cliCtx * cli . Context ) ( * wallet . Wallet , error ) {
2020-08-31 19:46:45 +00:00
return nil , errors . New ( "no wallet found, create a new one with validator wallet-v2 create" )
} )
2020-08-25 01:37:25 +00:00
if err != nil {
2020-09-03 15:11:17 +00:00
return errors . Wrap ( err , "could not open wallet" )
2020-08-25 01:37:25 +00:00
}
2020-09-17 01:34:42 +00:00
s . wallet = w
2020-09-25 20:43:12 +00:00
log . WithFields ( logrus . Fields {
"wallet" : w . AccountsDir ( ) ,
"keymanager-kind" : w . KeymanagerKind ( ) . String ( ) ,
} ) . Info ( "Opened validator wallet" )
2020-09-17 01:34:42 +00:00
keyManagerV2 , err = w . InitializeKeymanager (
2020-08-31 19:46:45 +00:00
cliCtx . Context , false , /* skipMnemonicConfirm */
2020-08-25 01:37:25 +00:00
)
if err != nil {
2020-09-03 15:11:17 +00:00
return errors . Wrap ( err , "could not read keymanager for wallet" )
2020-08-25 01:37:25 +00:00
}
2020-09-17 01:34:42 +00:00
if err := w . LockWalletConfigFile ( cliCtx . Context ) ; err != nil {
2020-08-25 01:37:25 +00:00
log . Fatalf ( "Could not get a lock on wallet file. Please check if you have another validator instance running and using the same wallet: %v" , err )
}
2020-09-08 16:42:06 +00:00
accountsDir = s . wallet . AccountsDir ( )
2020-08-10 17:48:41 +00:00
}
2020-07-24 21:36:28 +00:00
} else {
keyManagerV1 , err = selectV1Keymanager ( cliCtx )
if err != nil {
2020-09-03 15:11:17 +00:00
return err
2020-07-24 21:36:28 +00:00
}
2020-07-08 05:01:09 +00:00
}
2020-09-08 16:42:06 +00:00
dataDir := moveDb ( cliCtx , accountsDir )
2020-05-07 15:14:08 +00:00
clearFlag := cliCtx . Bool ( cmd . ClearDB . Name )
forceClearFlag := cliCtx . Bool ( cmd . ForceClearDB . Name )
2020-01-08 18:16:17 +00:00
if clearFlag || forceClearFlag {
2020-03-19 21:46:44 +00:00
if dataDir == "" {
dataDir = cmd . DefaultDataDir ( )
2020-06-25 18:02:07 +00:00
if dataDir == "" {
log . Fatal (
"Could not determine your system's HOME path, please specify a --datadir you wish " +
"to use for your validator data" ,
)
}
2020-03-19 21:46:44 +00:00
}
2020-09-03 15:11:17 +00:00
if err := clearDB ( dataDir , forceClearFlag ) ; err != nil {
return err
2020-01-08 18:16:17 +00:00
}
}
2020-04-30 23:17:06 +00:00
log . WithField ( "databasePath" , dataDir ) . Info ( "Checking DB" )
2020-01-08 18:16:17 +00:00
2020-09-03 15:11:17 +00:00
valDB , err := kv . NewKVStore ( dataDir , nil )
2020-08-14 02:49:57 +00:00
if err != nil {
2020-09-03 15:11:17 +00:00
return errors . Wrap ( err , "could not initialize db" )
2020-08-14 02:49:57 +00:00
}
2020-09-03 15:11:17 +00:00
s . db = valDB
2020-09-30 20:55:56 +00:00
if ! cliCtx . Bool ( cmd . DisableMonitoringFlag . Name ) {
if err := s . registerPrometheusService ( ) ; err != nil {
return err
}
2018-06-20 03:59:02 +00:00
}
2020-05-20 15:23:22 +00:00
if featureconfig . Get ( ) . SlasherProtection {
2020-09-03 15:11:17 +00:00
if err := s . registerSlasherClientService ( ) ; err != nil {
return err
2020-05-20 15:23:22 +00:00
}
}
2020-09-03 15:11:17 +00:00
if err := s . registerClientService ( keyManagerV1 , keyManagerV2 ) ; err != nil {
return err
2019-01-13 07:01:11 +00:00
}
2020-09-30 20:55:56 +00:00
if cliCtx . Bool ( flags . EnableRPCFlag . Name ) {
if err := s . registerRPCService ( cliCtx ) ; err != nil {
return err
}
if err := s . registerRPCGatewayService ( cliCtx ) ; err != nil {
return err
}
2020-08-14 02:49:57 +00:00
}
2020-09-03 15:11:17 +00:00
return nil
2018-06-02 22:29:35 +00:00
}
2020-09-08 16:42:06 +00:00
func moveDb ( cliCtx * cli . Context , accountsDir string ) string {
dataDir := cliCtx . String ( cmd . DataDirFlag . Name )
if accountsDir != "" {
dataFile := filepath . Join ( dataDir , kv . ProtectionDbFileName )
newDataFile := filepath . Join ( accountsDir , kv . ProtectionDbFileName )
if fileutil . FileExists ( dataFile ) && ! fileutil . FileExists ( newDataFile ) {
log . WithFields ( logrus . Fields {
"oldDbPath" : dataDir ,
"walletDir" : accountsDir ,
} ) . Info ( "Moving validator protection db to wallet dir" )
2020-09-10 21:56:58 +00:00
err := fileutil . CopyFile ( dataFile , newDataFile )
if err != nil {
2020-09-08 16:42:06 +00:00
log . Fatal ( err )
}
}
dataDir = accountsDir
}
return dataDir
}
2020-09-03 15:11:17 +00:00
func ( s * ValidatorClient ) initializeForWeb ( cliCtx * cli . Context ) error {
clearFlag := cliCtx . Bool ( cmd . ClearDB . Name )
forceClearFlag := cliCtx . Bool ( cmd . ForceClearDB . Name )
dataDir := cliCtx . String ( cmd . DataDirFlag . Name )
if clearFlag || forceClearFlag {
if dataDir == "" {
dataDir = cmd . DefaultDataDir ( )
if dataDir == "" {
log . Fatal (
"Could not determine your system's HOME path, please specify a --datadir you wish " +
"to use for your validator data" ,
)
2018-06-11 22:21:24 +00:00
}
2018-06-02 22:29:35 +00:00
2020-09-03 15:11:17 +00:00
}
if err := clearDB ( dataDir , forceClearFlag ) ; err != nil {
return err
2020-08-25 01:37:25 +00:00
}
2020-08-10 17:48:41 +00:00
}
2020-09-03 15:11:17 +00:00
log . WithField ( "databasePath" , dataDir ) . Info ( "Checking DB" )
valDB , err := kv . NewKVStore ( dataDir , make ( [ ] [ 48 ] byte , 0 ) )
if err != nil {
return errors . Wrap ( err , "could not initialize db" )
}
s . db = valDB
2020-09-30 20:55:56 +00:00
if ! cliCtx . Bool ( cmd . DisableMonitoringFlag . Name ) {
if err := s . registerPrometheusService ( ) ; err != nil {
return err
}
2020-09-03 15:11:17 +00:00
}
if featureconfig . Get ( ) . SlasherProtection {
if err := s . registerSlasherClientService ( ) ; err != nil {
return err
}
}
if err := s . registerClientService ( nil , nil ) ; err != nil {
return err
}
if err := s . registerRPCService ( cliCtx ) ; err != nil {
return err
}
if err := s . registerRPCGatewayService ( cliCtx ) ; err != nil {
return err
}
2020-10-09 14:58:30 +00:00
return s . registerWebService ( cliCtx )
2018-06-04 19:31:42 +00:00
}
2020-05-07 15:14:08 +00:00
func ( s * ValidatorClient ) registerPrometheusService ( ) error {
2020-09-23 08:59:49 +00:00
service := prometheus . NewService (
2020-07-08 08:21:06 +00:00
fmt . Sprintf ( "%s:%d" , s . cliCtx . String ( cmd . MonitoringHostFlag . Name ) , s . cliCtx . Int ( flags . MonitoringPortFlag . Name ) ) ,
2019-01-13 07:01:11 +00:00
s . services ,
)
logrus . AddHook ( prometheus . NewLogrusCollector ( ) )
return s . services . RegisterService ( service )
}
2019-01-23 02:52:39 +00:00
2020-07-08 05:01:09 +00:00
func ( s * ValidatorClient ) registerClientService (
keyManager v1 . KeyManager ,
keyManagerV2 v2 . IKeymanager ,
) error {
2020-05-07 15:14:08 +00:00
endpoint := s . cliCtx . String ( flags . BeaconRPCProviderFlag . Name )
dataDir := s . cliCtx . String ( cmd . DataDirFlag . Name )
logValidatorBalances := ! s . cliCtx . Bool ( flags . DisablePenaltyRewardLogFlag . Name )
2020-05-19 13:44:54 +00:00
emitAccountMetrics := ! s . cliCtx . Bool ( flags . DisableAccountMetricsFlag . Name )
2020-05-07 15:14:08 +00:00
cert := s . cliCtx . String ( flags . CertFlag . Name )
graffiti := s . cliCtx . String ( flags . GraffitiFlag . Name )
maxCallRecvMsgSize := s . cliCtx . Int ( cmd . GrpcMaxCallRecvMsgSizeFlag . Name )
grpcRetries := s . cliCtx . Uint ( flags . GrpcRetriesFlag . Name )
2020-07-22 03:45:52 +00:00
grpcRetryDelay := s . cliCtx . Duration ( flags . GrpcRetryDelayFlag . Name )
2020-05-20 15:23:22 +00:00
var sp * slashing_protection . Service
var protector slashing_protection . Protector
if err := s . services . FetchService ( & sp ) ; err == nil {
protector = sp
}
2020-09-09 09:48:52 +00:00
v , err := client . NewValidatorService ( s . cliCtx . Context , & client . Config {
2020-01-13 17:29:43 +00:00
Endpoint : endpoint ,
DataDir : dataDir ,
KeyManager : keyManager ,
2020-07-08 05:01:09 +00:00
KeyManagerV2 : keyManagerV2 ,
2020-01-13 17:29:43 +00:00
LogValidatorBalances : logValidatorBalances ,
2020-02-05 17:49:27 +00:00
EmitAccountMetrics : emitAccountMetrics ,
2020-01-13 17:29:43 +00:00
CertFlag : cert ,
GraffitiFlag : graffiti ,
GrpcMaxCallRecvMsgSizeFlag : maxCallRecvMsgSize ,
2020-02-24 18:00:22 +00:00
GrpcRetriesFlag : grpcRetries ,
2020-07-22 03:45:52 +00:00
GrpcRetryDelay : grpcRetryDelay ,
2020-05-07 15:14:08 +00:00
GrpcHeadersFlag : s . cliCtx . String ( flags . GrpcHeadersFlag . Name ) ,
2020-05-20 15:23:22 +00:00
Protector : protector ,
2020-08-14 02:49:57 +00:00
ValDB : s . db ,
2020-09-03 15:11:17 +00:00
UseWeb : s . cliCtx . Bool ( flags . EnableWebFlag . Name ) ,
WalletInitializedFeed : s . walletInitialized ,
2019-01-30 12:28:53 +00:00
} )
2020-05-20 15:23:22 +00:00
2019-02-13 23:49:06 +00:00
if err != nil {
2019-08-02 02:27:38 +00:00
return errors . Wrap ( err , "could not initialize client service" )
2019-02-13 23:49:06 +00:00
}
2019-01-23 02:52:39 +00:00
return s . services . RegisterService ( v )
}
2020-05-20 15:23:22 +00:00
func ( s * ValidatorClient ) registerSlasherClientService ( ) error {
endpoint := s . cliCtx . String ( flags . SlasherRPCProviderFlag . Name )
if endpoint == "" {
return errors . New ( "external slasher feature flag is set but no slasher endpoint is configured" )
}
cert := s . cliCtx . String ( flags . SlasherCertFlag . Name )
maxCallRecvMsgSize := s . cliCtx . Int ( cmd . GrpcMaxCallRecvMsgSizeFlag . Name )
grpcRetries := s . cliCtx . Uint ( flags . GrpcRetriesFlag . Name )
2020-07-22 03:45:52 +00:00
grpcRetryDelay := s . cliCtx . Duration ( flags . GrpcRetryDelayFlag . Name )
2020-09-23 08:59:49 +00:00
sp , err := slashing_protection . NewService ( s . cliCtx . Context , & slashing_protection . Config {
2020-05-20 15:23:22 +00:00
Endpoint : endpoint ,
CertFlag : cert ,
GrpcMaxCallRecvMsgSizeFlag : maxCallRecvMsgSize ,
GrpcRetriesFlag : grpcRetries ,
2020-07-22 03:45:52 +00:00
GrpcRetryDelay : grpcRetryDelay ,
2020-05-20 15:23:22 +00:00
GrpcHeadersFlag : s . cliCtx . String ( flags . GrpcHeadersFlag . Name ) ,
} )
if err != nil {
return errors . Wrap ( err , "could not initialize client service" )
}
return s . services . RegisterService ( sp )
}
2020-01-04 03:51:53 +00:00
2020-08-14 02:49:57 +00:00
func ( s * ValidatorClient ) registerRPCService ( cliCtx * cli . Context ) error {
2020-08-12 23:33:15 +00:00
var vs * client . ValidatorService
if err := s . services . FetchService ( & vs ) ; err != nil {
return err
}
2020-08-14 02:49:57 +00:00
rpcHost := cliCtx . String ( flags . RPCHost . Name )
rpcPort := cliCtx . Int ( flags . RPCPort . Name )
2020-09-04 19:03:18 +00:00
nodeGatewayEndpoint := cliCtx . String ( flags . BeaconRPCGatewayProviderFlag . Name )
2020-10-10 02:07:28 +00:00
walletDir := cliCtx . String ( flags . WalletDirFlag . Name )
2020-09-09 09:48:52 +00:00
server := rpc . NewServer ( cliCtx . Context , & rpc . Config {
2020-09-03 15:11:17 +00:00
ValDB : s . db ,
Host : rpcHost ,
Port : fmt . Sprintf ( "%d" , rpcPort ) ,
WalletInitializedFeed : s . walletInitialized ,
ValidatorService : vs ,
2020-09-03 23:25:56 +00:00
SyncChecker : vs ,
2020-09-08 20:54:56 +00:00
GenesisFetcher : vs ,
2020-09-04 19:03:18 +00:00
NodeGatewayEndpoint : nodeGatewayEndpoint ,
2020-10-10 02:07:28 +00:00
WalletDir : walletDir ,
2020-08-14 02:49:57 +00:00
} )
2020-08-12 23:33:15 +00:00
return s . services . RegisterService ( server )
}
2020-08-14 02:49:57 +00:00
func ( s * ValidatorClient ) registerRPCGatewayService ( cliCtx * cli . Context ) error {
gatewayHost := cliCtx . String ( flags . GRPCGatewayHost . Name )
gatewayPort := cliCtx . Int ( flags . GRPCGatewayPort . Name )
rpcHost := cliCtx . String ( flags . RPCHost . Name )
rpcPort := cliCtx . Int ( flags . RPCPort . Name )
rpcAddr := fmt . Sprintf ( "%s:%d" , rpcHost , rpcPort )
gatewayAddress := fmt . Sprintf ( "%s:%d" , gatewayHost , gatewayPort )
2020-09-04 19:03:18 +00:00
allowedOrigins := strings . Split ( cliCtx . String ( flags . GPRCGatewayCorsDomain . Name ) , "," )
2020-08-14 02:49:57 +00:00
gatewaySrv := gateway . New (
2020-09-09 09:48:52 +00:00
cliCtx . Context ,
2020-08-14 02:49:57 +00:00
rpcAddr ,
gatewayAddress ,
allowedOrigins ,
)
return s . services . RegisterService ( gatewaySrv )
}
2020-10-09 14:58:30 +00:00
func ( s * ValidatorClient ) registerWebService ( cliCtx * cli . Context ) error {
host := cliCtx . String ( flags . WebHostFlag . Name )
port := cliCtx . Uint64 ( flags . WebPortFlag . Name )
webAddress := fmt . Sprintf ( "%s:%d" , host , port )
srv := web . NewServer ( webAddress )
return s . services . RegisterService ( srv )
}
2020-07-08 05:01:09 +00:00
// Selects the key manager depending on the options provided by the user.
func selectV1Keymanager ( ctx * cli . Context ) ( v1 . KeyManager , error ) {
2020-01-24 17:21:31 +00:00
manager := strings . ToLower ( ctx . String ( flags . KeyManager . Name ) )
opts := ctx . String ( flags . KeyManagerOpts . Name )
if opts == "" {
opts = "{}"
2020-02-03 17:13:58 +00:00
} else if ! strings . HasPrefix ( opts , "{" ) {
fileopts , err := ioutil . ReadFile ( opts )
if err != nil {
return nil , errors . Wrap ( err , "Failed to read keymanager options file" )
}
opts = string ( fileopts )
2020-01-04 03:51:53 +00:00
}
2020-01-24 17:21:31 +00:00
if manager == "" {
// Attempt to work out keymanager from deprecated vars.
if unencryptedKeys := ctx . String ( flags . UnencryptedKeysFlag . Name ) ; unencryptedKeys != "" {
manager = "unencrypted"
opts = fmt . Sprintf ( ` { "path":%q} ` , unencryptedKeys )
log . Warn ( fmt . Sprintf ( "--unencrypted-keys flag is deprecated. Please use --keymanager=unencrypted --keymanageropts='%s'" , opts ) )
2020-03-19 21:46:44 +00:00
} else if numValidatorKeys := ctx . Uint64 ( flags . InteropNumValidators . Name ) ; numValidatorKeys > 0 {
2020-01-24 17:21:31 +00:00
manager = "interop"
2020-03-19 21:46:44 +00:00
opts = fmt . Sprintf ( ` { "keys":%d,"offset":%d} ` , numValidatorKeys , ctx . Uint64 ( flags . InteropStartIndex . Name ) )
2020-01-24 17:21:31 +00:00
log . Warn ( fmt . Sprintf ( "--interop-num-validators and --interop-start-index flags are deprecated. Please use --keymanager=interop --keymanageropts='%s'" , opts ) )
} else if keystorePath := ctx . String ( flags . KeystorePathFlag . Name ) ; keystorePath != "" {
manager = "keystore"
opts = fmt . Sprintf ( ` { "path":%q,"passphrase":%q} ` , keystorePath , ctx . String ( flags . PasswordFlag . Name ) )
log . Warn ( fmt . Sprintf ( "--keystore-path flag is deprecated. Please use --keymanager=keystore --keymanageropts='%s'" , opts ) )
} else {
// Default if no choice made
manager = "keystore"
passphrase := ctx . String ( flags . PasswordFlag . Name )
if passphrase == "" {
log . Warn ( "Implicit selection of keymanager is deprecated. Please use --keymanager=keystore or select a different keymanager" )
} else {
opts = fmt . Sprintf ( ` { "passphrase":%q} ` , passphrase )
log . Warn ( ` Implicit selection of keymanager is deprecated. Please use --keymanager=keystore --keymanageropts=' { "passphrase":"<password>"}' or select a different keymanager ` )
}
}
2020-01-04 03:51:53 +00:00
}
2020-07-08 05:01:09 +00:00
var km v1 . KeyManager
2020-01-24 17:21:31 +00:00
var help string
var err error
switch manager {
case "interop" :
2020-07-08 05:01:09 +00:00
km , help , err = v1 . NewInterop ( opts )
2020-01-24 17:21:31 +00:00
case "unencrypted" :
2020-07-08 05:01:09 +00:00
km , help , err = v1 . NewUnencrypted ( opts )
2020-01-24 17:21:31 +00:00
case "keystore" :
2020-07-08 05:01:09 +00:00
km , help , err = v1 . NewKeystore ( opts )
2020-02-03 17:13:58 +00:00
case "wallet" :
2020-07-08 05:01:09 +00:00
km , help , err = v1 . NewWallet ( opts )
2020-04-14 20:27:03 +00:00
case "remote" :
2020-07-08 05:01:09 +00:00
km , help , err = v1 . NewRemoteWallet ( opts )
2020-01-24 17:21:31 +00:00
default :
return nil , fmt . Errorf ( "unknown keymanager %q" , manager )
}
if err != nil {
2020-06-08 14:03:14 +00:00
if help != "" {
// Print help for the keymanager
fmt . Println ( help )
}
2020-01-24 17:21:31 +00:00
return nil , err
}
return km , nil
2020-01-04 03:51:53 +00:00
}
2020-01-08 18:16:17 +00:00
2020-09-03 15:11:17 +00:00
func clearDB ( dataDir string , force bool ) error {
2020-01-08 18:16:17 +00:00
var err error
clearDBConfirmed := force
if ! force {
actionText := "This will delete your validator's historical actions database stored in your data directory. " +
"This may lead to potential slashing - do you want to proceed? (Y/N)"
deniedText := "The historical actions database will not be deleted. No changes have been made."
clearDBConfirmed , err = cmd . ConfirmAction ( actionText , deniedText )
if err != nil {
2020-06-23 21:11:20 +00:00
return errors . Wrapf ( err , "Could not clear DB in dir %s" , dataDir )
2020-01-08 18:16:17 +00:00
}
}
if clearDBConfirmed {
2020-09-03 15:11:17 +00:00
valDB , err := kv . NewKVStore ( dataDir , nil )
2020-01-08 18:16:17 +00:00
if err != nil {
return errors . Wrapf ( err , "Could not create DB in dir %s" , dataDir )
}
2020-10-09 09:28:35 +00:00
if err := valDB . Close ( ) ; err != nil {
return errors . Wrapf ( err , "could not close DB in dir %s" , dataDir )
}
2020-01-08 18:16:17 +00:00
log . Warning ( "Removing database" )
if err := valDB . ClearDB ( ) ; err != nil {
return errors . Wrapf ( err , "Could not clear DB in dir %s" , dataDir )
}
}
return nil
}