mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
validator client initialization cleanup (#15080)
* cleanup * fixing optimal sort order for struct * reverting clictx change based on kasey's feedback * adding in fix for old trace file flag * more cleanup for clarity * optimizing if statement check and fixing wallet open on web enable * optimizing if statement check and fixing wallet open on web enable * some more cleanup and bug fix on open wallet * reverting debug.go changes will handle in a separate PR * removing useless comment * changing useWeb to enableAPI * fixing tests and linting * manu feedback and one optimization removing auth token check * gaz
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- The `--rpc` flag will now properly enable the keymanager APIs without web. The `--web` will enable both validator api endpoints and web.
|
||||
@@ -186,6 +186,7 @@ func OpenWalletOrElseCli(cliCtx *cli.Context, otherwise func(cliCtx *cli.Context
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return OpenWallet(cliCtx.Context, &Config{
|
||||
WalletDir: walletDir,
|
||||
WalletPassword: walletPassword,
|
||||
@@ -291,6 +292,10 @@ func OpenWallet(_ context.Context, cfg *Config) (*Wallet, error) {
|
||||
return nil, errors.Wrap(err, "could not read keymanager kind for wallet")
|
||||
}
|
||||
accountsPath := filepath.Join(cfg.WalletDir, keymanagerKind.String())
|
||||
log.WithFields(logrus.Fields{
|
||||
"wallet": accountsPath,
|
||||
"keymanagerKind": keymanagerKind.String(),
|
||||
}).Info("Opened validator wallet")
|
||||
return &Wallet{
|
||||
walletDir: cfg.WalletDir,
|
||||
accountsPath: accountsPath,
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestValidator_SignValidatorRegistrationRequest(t *testing.T) {
|
||||
v := validator{
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
genesisTime: 0,
|
||||
}
|
||||
v.signedValidatorRegistrations[bytesutil.ToBytes48(validatorKey.PublicKey().Marshal())] = ðpb.SignedValidatorRegistrationV1{
|
||||
@@ -201,7 +201,7 @@ func TestValidator_SignValidatorRegistrationRequest(t *testing.T) {
|
||||
v := validator{
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
genesisTime: 0,
|
||||
}
|
||||
v.signedValidatorRegistrations[bytesutil.ToBytes48(validatorKey.PublicKey().Marshal())] = ðpb.SignedValidatorRegistrationV1{
|
||||
@@ -229,7 +229,7 @@ func TestValidator_SignValidatorRegistrationRequest(t *testing.T) {
|
||||
v := validator{
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
genesisTime: 0,
|
||||
}
|
||||
v.signedValidatorRegistrations[bytesutil.ToBytes48(validatorKey.PublicKey().Marshal())] = ðpb.SignedValidatorRegistrationV1{
|
||||
@@ -257,7 +257,7 @@ func TestValidator_SignValidatorRegistrationRequest(t *testing.T) {
|
||||
v := validator{
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
genesisTime: 0,
|
||||
}
|
||||
return &v
|
||||
|
||||
@@ -54,7 +54,7 @@ type ValidatorService struct {
|
||||
web3SignerConfig *remoteweb3signer.SetupConfig
|
||||
proposerSettings *proposer.Settings
|
||||
validatorsRegBatchSize int
|
||||
useWeb bool
|
||||
enableAPI bool
|
||||
emitAccountMetrics bool
|
||||
logValidatorPerformance bool
|
||||
distributed bool
|
||||
@@ -80,7 +80,7 @@ type Config struct {
|
||||
Web3SignerConfig *remoteweb3signer.SetupConfig
|
||||
ProposerSettings *proposer.Settings
|
||||
ValidatorsRegBatchSize int
|
||||
UseWeb bool
|
||||
EnableAPI bool
|
||||
LogValidatorPerformance bool
|
||||
EmitAccountMetrics bool
|
||||
Distributed bool
|
||||
@@ -103,7 +103,7 @@ func NewValidatorService(ctx context.Context, cfg *Config) (*ValidatorService, e
|
||||
web3SignerConfig: cfg.Web3SignerConfig,
|
||||
proposerSettings: cfg.ProposerSettings,
|
||||
validatorsRegBatchSize: cfg.ValidatorsRegBatchSize,
|
||||
useWeb: cfg.UseWeb,
|
||||
enableAPI: cfg.EnableAPI,
|
||||
emitAccountMetrics: cfg.EmitAccountMetrics,
|
||||
logValidatorPerformance: cfg.LogValidatorPerformance,
|
||||
distributed: cfg.Distributed,
|
||||
@@ -215,7 +215,7 @@ func (v *ValidatorService) Start() {
|
||||
submittedAggregates: make(map[submittedAttKey]*submittedAtt),
|
||||
logValidatorPerformance: v.logValidatorPerformance,
|
||||
emitAccountMetrics: v.emitAccountMetrics,
|
||||
useWeb: v.useWeb,
|
||||
enableAPI: v.enableAPI,
|
||||
distributed: v.distributed,
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ type validator struct {
|
||||
submittedAggregates map[submittedAttKey]*submittedAtt
|
||||
logValidatorPerformance bool
|
||||
emitAccountMetrics bool
|
||||
useWeb bool
|
||||
enableAPI bool
|
||||
distributed bool
|
||||
domainDataLock sync.RWMutex
|
||||
attLogsLock sync.Mutex
|
||||
@@ -140,33 +140,33 @@ func (v *validator) WaitForKeymanagerInitialization(ctx context.Context) error {
|
||||
return errors.Wrap(err, "unable to retrieve valid genesis validators root while initializing key manager")
|
||||
}
|
||||
|
||||
if v.useWeb && v.wallet == nil {
|
||||
log.Info("Waiting for keymanager to initialize validator client with web UI")
|
||||
// if wallet is not set, wait for it to be set through the UI
|
||||
switch {
|
||||
case v.wallet != nil:
|
||||
if v.web3SignerConfig != nil {
|
||||
v.web3SignerConfig.GenesisValidatorsRoot = genesisRoot
|
||||
}
|
||||
keyManager, err := v.wallet.InitializeKeymanager(ctx, accountsiface.InitKeymanagerConfig{ListenForChanges: true, Web3SignerConfig: v.web3SignerConfig})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not initialize key manager")
|
||||
}
|
||||
v.km = keyManager
|
||||
case v.interopKeysConfig != nil:
|
||||
keyManager, err := local.NewInteropKeymanager(ctx, v.interopKeysConfig.Offset, v.interopKeysConfig.NumValidatorKeys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not generate interop keys for key manager")
|
||||
}
|
||||
v.km = keyManager
|
||||
case v.enableAPI:
|
||||
km, err := waitForWebWalletInitialization(ctx, v.walletInitializedFeed, v.walletInitializedChan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.km = km
|
||||
} else {
|
||||
if v.interopKeysConfig != nil {
|
||||
keyManager, err := local.NewInteropKeymanager(ctx, v.interopKeysConfig.Offset, v.interopKeysConfig.NumValidatorKeys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not generate interop keys for key manager")
|
||||
}
|
||||
v.km = keyManager
|
||||
} else if v.wallet == nil {
|
||||
return errors.New("wallet not set")
|
||||
} else {
|
||||
if v.web3SignerConfig != nil {
|
||||
v.web3SignerConfig.GenesisValidatorsRoot = genesisRoot
|
||||
}
|
||||
keyManager, err := v.wallet.InitializeKeymanager(ctx, accountsiface.InitKeymanagerConfig{ListenForChanges: true, Web3SignerConfig: v.web3SignerConfig})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not initialize key manager")
|
||||
}
|
||||
v.km = keyManager
|
||||
}
|
||||
default:
|
||||
return wallet.ErrNoWalletFound
|
||||
}
|
||||
if v.km == nil {
|
||||
return errors.New("key manager not set")
|
||||
}
|
||||
recheckKeys(ctx, v.db, v.km)
|
||||
return nil
|
||||
@@ -181,6 +181,7 @@ func waitForWebWalletInitialization(
|
||||
ctx, span := trace.StartSpan(ctx, "validator.waitForWebWalletInitialization")
|
||||
defer span.End()
|
||||
|
||||
log.Info("Waiting for keymanager to initialize validator client with web UI or /v2/validator/wallet/create REST api")
|
||||
sub := walletInitializedEvent.Subscribe(walletChan)
|
||||
defer sub.Unsubscribe()
|
||||
for {
|
||||
|
||||
@@ -1311,9 +1311,9 @@ func TestValidator_WaitForKeymanagerInitialization_web3Signer(t *testing.T) {
|
||||
set.String(flags.WalletDirFlag.Name, newDir, "")
|
||||
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
|
||||
v := validator{
|
||||
db: db,
|
||||
useWeb: false,
|
||||
wallet: w,
|
||||
db: db,
|
||||
enableAPI: false,
|
||||
wallet: w,
|
||||
web3SignerConfig: &remoteweb3signer.SetupConfig{
|
||||
BaseEndpoint: "http://localhost:8545",
|
||||
ProvidedPublicKeys: []string{"0xa2b5aaad9c6efefe7bb9b1243a043404f3362937cfb6b31833929833173f476630ea2cfeb0d9ddf15f97ca8685948820"},
|
||||
@@ -1340,7 +1340,7 @@ func TestValidator_WaitForKeymanagerInitialization_Web(t *testing.T) {
|
||||
walletChan := make(chan *wallet.Wallet, 1)
|
||||
v := validator{
|
||||
db: db,
|
||||
useWeb: true,
|
||||
enableAPI: true,
|
||||
walletInitializedFeed: &event.Feed{},
|
||||
walletInitializedChan: walletChan,
|
||||
}
|
||||
@@ -1372,8 +1372,8 @@ func TestValidator_WaitForKeymanagerInitialization_Interop(t *testing.T) {
|
||||
err := db.SaveGenesisValidatorsRoot(ctx, root)
|
||||
require.NoError(t, err)
|
||||
v := validator{
|
||||
db: db,
|
||||
useWeb: false,
|
||||
db: db,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 2,
|
||||
Offset: 1,
|
||||
@@ -1460,7 +1460,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 2,
|
||||
Offset: 1,
|
||||
@@ -1551,7 +1551,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 2,
|
||||
Offset: 1,
|
||||
@@ -1637,7 +1637,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 2,
|
||||
Offset: 1,
|
||||
@@ -1707,7 +1707,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 1,
|
||||
Offset: 1,
|
||||
@@ -1780,7 +1780,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 1,
|
||||
Offset: 1,
|
||||
@@ -1849,7 +1849,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 1,
|
||||
Offset: 1,
|
||||
@@ -1906,7 +1906,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 1,
|
||||
Offset: 1,
|
||||
@@ -1953,7 +1953,7 @@ func TestValidator_PushSettings(t *testing.T) {
|
||||
db: db,
|
||||
pubkeyToStatus: make(map[[fieldparams.BLSPubkeyLength]byte]*validatorStatus),
|
||||
signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1),
|
||||
useWeb: false,
|
||||
enableAPI: false,
|
||||
interopKeysConfig: &local.InteropKeymanagerConfig{
|
||||
NumValidatorKeys: 1,
|
||||
Offset: 1,
|
||||
|
||||
@@ -33,7 +33,6 @@ go_library(
|
||||
"//validator:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//api/server/middleware:go_default_library",
|
||||
"//async/event:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/middleware"
|
||||
"github.com/prysmaticlabs/prysm/v5/async/event"
|
||||
"github.com/prysmaticlabs/prysm/v5/cmd"
|
||||
@@ -86,17 +85,6 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) {
|
||||
// Warn if user's platform is not supported
|
||||
prereqs.WarnIfPlatformNotSupported(cliCtx.Context)
|
||||
|
||||
registry := runtime.NewServiceRegistry()
|
||||
ctx, cancel := context.WithCancel(cliCtx.Context)
|
||||
validatorClient := &ValidatorClient{
|
||||
cliCtx: cliCtx,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
services: registry,
|
||||
walletInitializedFeed: new(event.Feed),
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
|
||||
if err := features.ConfigureValidator(cliCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -111,23 +99,28 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// initialize router used for endpoints
|
||||
router := http.NewServeMux()
|
||||
// If the --web flag is enabled to administer the validator
|
||||
// client via a web portal, we start the validator client in a different way.
|
||||
// Change Web flag name to enable keymanager API, look at merging initializeFromCLI and initializeForWeb maybe after WebUI DEPRECATED.
|
||||
if cliCtx.IsSet(flags.EnableWebFlag.Name) {
|
||||
if cliCtx.IsSet(flags.Web3SignerURLFlag.Name) || cliCtx.IsSet(flags.Web3SignerPublicValidatorKeysFlag.Name) {
|
||||
log.Warn("Remote Keymanager API enabled. Prysm web does not properly support web3signer at this time")
|
||||
}
|
||||
log.Info("Enabling web portal to manage the validator client")
|
||||
if err := validatorClient.initializeForWeb(cliCtx, router); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return validatorClient, nil
|
||||
w, err := getWallet(cliCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := validatorClient.initializeFromCLI(cliCtx, router); err != nil {
|
||||
registry := runtime.NewServiceRegistry()
|
||||
ctx, cancel := context.WithCancel(cliCtx.Context)
|
||||
validatorClient := &ValidatorClient{
|
||||
cliCtx: cliCtx,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
services: registry,
|
||||
wallet: w,
|
||||
walletInitializedFeed: new(event.Feed),
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
|
||||
if err := validatorClient.initializeDB(cliCtx); err != nil {
|
||||
return nil, errors.Wrapf(err, "could not initialize database")
|
||||
}
|
||||
|
||||
if err := validatorClient.registerServices(cliCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -228,93 +221,40 @@ func (c *ValidatorClient) getLegacyDatabaseLocation(
|
||||
return dataDir, dataFile, nil
|
||||
}
|
||||
|
||||
func (c *ValidatorClient) initializeFromCLI(cliCtx *cli.Context, router *http.ServeMux) error {
|
||||
isInteropNumValidatorsSet := cliCtx.IsSet(flags.InteropNumValidators.Name)
|
||||
isWeb3SignerURLFlagSet := cliCtx.IsSet(flags.Web3SignerURLFlag.Name)
|
||||
|
||||
if !isInteropNumValidatorsSet {
|
||||
// Custom Check For Web3Signer
|
||||
if isWeb3SignerURLFlagSet {
|
||||
c.wallet = wallet.NewWalletForWeb3Signer(cliCtx)
|
||||
} else {
|
||||
w, err := wallet.OpenWalletOrElseCli(cliCtx, func(cliCtx *cli.Context) (*wallet.Wallet, error) {
|
||||
return nil, wallet.ErrNoWalletFound
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not open wallet")
|
||||
}
|
||||
c.wallet = w
|
||||
// TODO(#9883) - Remove this when we have a better way to handle this.
|
||||
log.WithFields(logrus.Fields{
|
||||
"wallet": w.AccountsDir(),
|
||||
"keymanagerKind": w.KeymanagerKind().String(),
|
||||
}).Info("Opened validator wallet")
|
||||
}
|
||||
func getWallet(cliCtx *cli.Context) (*wallet.Wallet, error) {
|
||||
if cliCtx.IsSet(flags.InteropNumValidators.Name) {
|
||||
log.Info("no wallet required for interop validation")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err := c.initializeDB(cliCtx); err != nil {
|
||||
return errors.Wrapf(err, "could not initialize database")
|
||||
if cliCtx.IsSet(flags.Web3SignerURLFlag.Name) {
|
||||
return wallet.NewWalletForWeb3Signer(cliCtx), nil
|
||||
}
|
||||
|
||||
if !cliCtx.Bool(cmd.DisableMonitoringFlag.Name) {
|
||||
if err := c.registerPrometheusService(cliCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setWalletPasswordFilePath(cliCtx); err != nil {
|
||||
return nil, errors.Wrap(err, "could not read wallet password file")
|
||||
}
|
||||
if err := c.registerValidatorService(cliCtx); err != nil {
|
||||
return err
|
||||
w, err := wallet.OpenWalletOrElseCli(cliCtx, func(cliCtx *cli.Context) (*wallet.Wallet, error) {
|
||||
// handle nil wallet in key manager initialization, give a chance for user to create a wallet
|
||||
return nil, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not open wallet")
|
||||
}
|
||||
if cliCtx.Bool(flags.EnableRPCFlag.Name) {
|
||||
if err := c.registerRPCService(router); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (c *ValidatorClient) initializeForWeb(cliCtx *cli.Context, router *http.ServeMux) error {
|
||||
if cliCtx.IsSet(flags.Web3SignerURLFlag.Name) {
|
||||
// Custom Check For Web3Signer
|
||||
c.wallet = wallet.NewWalletForWeb3Signer(cliCtx)
|
||||
} else {
|
||||
// Read the wallet password file from the cli context.
|
||||
if err := setWalletPasswordFilePath(cliCtx); err != nil {
|
||||
return errors.Wrap(err, "could not read wallet password file")
|
||||
}
|
||||
|
||||
// Read the wallet from the specified path.
|
||||
w, err := wallet.OpenWalletOrElseCli(cliCtx, func(cliCtx *cli.Context) (*wallet.Wallet, error) {
|
||||
return nil, nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not open wallet")
|
||||
}
|
||||
c.wallet = w
|
||||
func (c *ValidatorClient) registerServices(cliCtx *cli.Context) error {
|
||||
if err := c.registerPrometheusService(cliCtx); err != nil {
|
||||
return errors.Wrapf(err, "could not register prometheus service")
|
||||
}
|
||||
|
||||
if err := c.initializeDB(cliCtx); err != nil {
|
||||
return errors.Wrapf(err, "could not initialize database")
|
||||
}
|
||||
|
||||
if !cliCtx.Bool(cmd.DisableMonitoringFlag.Name) {
|
||||
if err := c.registerPrometheusService(cliCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := c.registerValidatorService(cliCtx); err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "could not register validator service")
|
||||
}
|
||||
|
||||
if err := c.registerRPCService(router); err != nil {
|
||||
return err
|
||||
if err := c.registerRPCService(cliCtx); err != nil {
|
||||
return errors.Wrapf(err, "could not register RPC service")
|
||||
}
|
||||
|
||||
host := cliCtx.String(flags.HTTPServerHost.Name)
|
||||
port := cliCtx.Int(flags.HTTPServerPort.Name)
|
||||
webAddress := fmt.Sprintf("http://%s:%d", host, port)
|
||||
log.WithField("address", webAddress).Info(
|
||||
"Starting Prysm web UI on address, open in browser to access",
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -432,6 +372,10 @@ func (c *ValidatorClient) initializeDB(cliCtx *cli.Context) error {
|
||||
}
|
||||
|
||||
func (c *ValidatorClient) registerPrometheusService(cliCtx *cli.Context) error {
|
||||
if cliCtx.Bool(cmd.DisableMonitoringFlag.Name) {
|
||||
log.Info("Prometheus service disabled")
|
||||
return nil
|
||||
}
|
||||
var additionalHandlers []prometheus.Handler
|
||||
if cliCtx.IsSet(cmd.EnableBackupWebhookFlag.Name) {
|
||||
additionalHandlers = append(
|
||||
@@ -443,7 +387,7 @@ func (c *ValidatorClient) registerPrometheusService(cliCtx *cli.Context) error {
|
||||
)
|
||||
}
|
||||
service := prometheus.NewService(
|
||||
fmt.Sprintf("%s:%d", c.cliCtx.String(cmd.MonitoringHostFlag.Name), c.cliCtx.Int(flags.MonitoringPortFlag.Name)),
|
||||
fmt.Sprintf("%s:%d", cliCtx.String(cmd.MonitoringHostFlag.Name), cliCtx.Int(flags.MonitoringPortFlag.Name)),
|
||||
c.services,
|
||||
additionalHandlers...,
|
||||
)
|
||||
@@ -458,7 +402,7 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error {
|
||||
)
|
||||
|
||||
// Configure interop.
|
||||
if c.cliCtx.IsSet(flags.InteropNumValidators.Name) {
|
||||
if cliCtx.IsSet(flags.InteropNumValidators.Name) {
|
||||
interopKmConfig = &local.InteropKeymanagerConfig{
|
||||
Offset: cliCtx.Uint64(flags.InteropStartIndex.Name),
|
||||
NumValidatorKeys: cliCtx.Uint64(flags.InteropNumValidators.Name),
|
||||
@@ -467,8 +411,8 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error {
|
||||
|
||||
// Configure graffiti.
|
||||
graffitiStruct := &g.Graffiti{}
|
||||
if c.cliCtx.IsSet(flags.GraffitiFileFlag.Name) {
|
||||
graffitiFilePath := c.cliCtx.String(flags.GraffitiFileFlag.Name)
|
||||
if cliCtx.IsSet(flags.GraffitiFileFlag.Name) {
|
||||
graffitiFilePath := cliCtx.String(flags.GraffitiFileFlag.Name)
|
||||
|
||||
graffitiStruct, err = g.ParseGraffitiFile(graffitiFilePath)
|
||||
if err != nil {
|
||||
@@ -476,38 +420,38 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
web3signerConfig, err := Web3SignerConfig(c.cliCtx)
|
||||
web3signerConfig, err := Web3SignerConfig(cliCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ps, err := proposerSettings(c.cliCtx, c.db)
|
||||
ps, err := proposerSettings(cliCtx, c.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validatorService, err := client.NewValidatorService(c.cliCtx.Context, &client.Config{
|
||||
validatorService, err := client.NewValidatorService(cliCtx.Context, &client.Config{
|
||||
DB: c.db,
|
||||
Wallet: c.wallet,
|
||||
WalletInitializedFeed: c.walletInitializedFeed,
|
||||
GRPCMaxCallRecvMsgSize: c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
|
||||
GRPCRetries: c.cliCtx.Uint(flags.GRPCRetriesFlag.Name),
|
||||
GRPCRetryDelay: c.cliCtx.Duration(flags.GRPCRetryDelayFlag.Name),
|
||||
GRPCHeaders: strings.Split(c.cliCtx.String(flags.GRPCHeadersFlag.Name), ","),
|
||||
BeaconNodeGRPCEndpoint: c.cliCtx.String(flags.BeaconRPCProviderFlag.Name),
|
||||
BeaconNodeCert: c.cliCtx.String(flags.CertFlag.Name),
|
||||
BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name),
|
||||
GRPCMaxCallRecvMsgSize: cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
|
||||
GRPCRetries: cliCtx.Uint(flags.GRPCRetriesFlag.Name),
|
||||
GRPCRetryDelay: cliCtx.Duration(flags.GRPCRetryDelayFlag.Name),
|
||||
GRPCHeaders: strings.Split(cliCtx.String(flags.GRPCHeadersFlag.Name), ","),
|
||||
BeaconNodeGRPCEndpoint: cliCtx.String(flags.BeaconRPCProviderFlag.Name),
|
||||
BeaconNodeCert: cliCtx.String(flags.CertFlag.Name),
|
||||
BeaconApiEndpoint: cliCtx.String(flags.BeaconRESTApiProviderFlag.Name),
|
||||
BeaconApiTimeout: time.Second * 30,
|
||||
Graffiti: g.ParseHexGraffiti(c.cliCtx.String(flags.GraffitiFlag.Name)),
|
||||
Graffiti: g.ParseHexGraffiti(cliCtx.String(flags.GraffitiFlag.Name)),
|
||||
GraffitiStruct: graffitiStruct,
|
||||
InteropKmConfig: interopKmConfig,
|
||||
Web3SignerConfig: web3signerConfig,
|
||||
ProposerSettings: ps,
|
||||
ValidatorsRegBatchSize: c.cliCtx.Int(flags.ValidatorsRegistrationBatchSizeFlag.Name),
|
||||
UseWeb: c.cliCtx.Bool(flags.EnableWebFlag.Name),
|
||||
LogValidatorPerformance: !c.cliCtx.Bool(flags.DisablePenaltyRewardLogFlag.Name),
|
||||
EmitAccountMetrics: !c.cliCtx.Bool(flags.DisableAccountMetricsFlag.Name),
|
||||
Distributed: c.cliCtx.Bool(flags.EnableDistributed.Name),
|
||||
ValidatorsRegBatchSize: cliCtx.Int(flags.ValidatorsRegistrationBatchSizeFlag.Name),
|
||||
EnableAPI: cliCtx.Bool(flags.EnableWebFlag.Name) || cliCtx.Bool(flags.EnableRPCFlag.Name),
|
||||
LogValidatorPerformance: !cliCtx.Bool(flags.DisablePenaltyRewardLogFlag.Name),
|
||||
EmitAccountMetrics: !cliCtx.Bool(flags.DisableAccountMetricsFlag.Name),
|
||||
Distributed: cliCtx.Bool(flags.EnableDistributed.Name),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not initialize validator service")
|
||||
@@ -567,32 +511,36 @@ func proposerSettings(cliCtx *cli.Context, db iface.ValidatorDB) (*proposer.Sett
|
||||
return l.Load(cliCtx)
|
||||
}
|
||||
|
||||
func (c *ValidatorClient) registerRPCService(router *http.ServeMux) error {
|
||||
func (c *ValidatorClient) registerRPCService(cliCtx *cli.Context) error {
|
||||
serveWebUI := cliCtx.IsSet(flags.EnableWebFlag.Name)
|
||||
if !cliCtx.IsSet(flags.EnableRPCFlag.Name) && !serveWebUI {
|
||||
return nil
|
||||
}
|
||||
host := cliCtx.String(flags.HTTPServerHost.Name)
|
||||
port := cliCtx.Int(flags.HTTPServerPort.Name)
|
||||
authTokenPath := cliCtx.String(flags.AuthTokenPathFlag.Name)
|
||||
walletDir := cliCtx.String(flags.WalletDirFlag.Name)
|
||||
|
||||
var vs *client.ValidatorService
|
||||
if err := c.services.FetchService(&vs); err != nil {
|
||||
return err
|
||||
}
|
||||
authTokenPath := c.cliCtx.String(flags.AuthTokenPathFlag.Name)
|
||||
walletDir := c.cliCtx.String(flags.WalletDirFlag.Name)
|
||||
// if no auth token path flag was passed try to set a default value
|
||||
if authTokenPath == "" {
|
||||
authTokenPath = flags.AuthTokenPathFlag.Value
|
||||
// if a wallet dir is passed without an auth token then override the default with the wallet dir
|
||||
if walletDir != "" {
|
||||
authTokenPath = filepath.Join(walletDir, api.AuthTokenFileName)
|
||||
|
||||
if serveWebUI {
|
||||
if cliCtx.IsSet(flags.Web3SignerURLFlag.Name) || cliCtx.IsSet(flags.Web3SignerPublicValidatorKeysFlag.Name) {
|
||||
log.Warn("Remote Keymanager API enabled. Prysm web does not properly support web3signer at this time")
|
||||
}
|
||||
}
|
||||
host := c.cliCtx.String(flags.HTTPServerHost.Name)
|
||||
|
||||
if host != flags.DefaultHTTPServerHost {
|
||||
log.WithField("webHost", host).Warn(
|
||||
"You are using a non-default web host. Web traffic is served by HTTP, so be wary of " +
|
||||
"changing this parameter if you are exposing this host to the Internet!",
|
||||
)
|
||||
}
|
||||
port := c.cliCtx.Int(flags.HTTPServerPort.Name)
|
||||
var allowedOrigins []string
|
||||
if c.cliCtx.IsSet(flags.HTTPServerCorsDomain.Name) {
|
||||
allowedOrigins = strings.Split(c.cliCtx.String(flags.HTTPServerCorsDomain.Name), ",")
|
||||
if cliCtx.IsSet(flags.HTTPServerCorsDomain.Name) {
|
||||
allowedOrigins = strings.Split(cliCtx.String(flags.HTTPServerCorsDomain.Name), ",")
|
||||
} else {
|
||||
allowedOrigins = strings.Split(flags.HTTPServerCorsDomain.Value, ",")
|
||||
}
|
||||
@@ -601,17 +549,17 @@ func (c *ValidatorClient) registerRPCService(router *http.ServeMux) error {
|
||||
middleware.NormalizeQueryValuesHandler,
|
||||
middleware.CorsHandler(allowedOrigins),
|
||||
}
|
||||
s := rpc.NewServer(c.cliCtx.Context, &rpc.Config{
|
||||
s := rpc.NewServer(cliCtx.Context, &rpc.Config{
|
||||
HTTPHost: host,
|
||||
HTTPPort: port,
|
||||
GRPCMaxCallRecvMsgSize: c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
|
||||
GRPCRetries: c.cliCtx.Uint(flags.GRPCRetriesFlag.Name),
|
||||
GRPCRetryDelay: c.cliCtx.Duration(flags.GRPCRetryDelayFlag.Name),
|
||||
GRPCHeaders: strings.Split(c.cliCtx.String(flags.GRPCHeadersFlag.Name), ","),
|
||||
BeaconNodeGRPCEndpoint: c.cliCtx.String(flags.BeaconRPCProviderFlag.Name),
|
||||
BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name),
|
||||
GRPCMaxCallRecvMsgSize: cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
|
||||
GRPCRetries: cliCtx.Uint(flags.GRPCRetriesFlag.Name),
|
||||
GRPCRetryDelay: cliCtx.Duration(flags.GRPCRetryDelayFlag.Name),
|
||||
GRPCHeaders: strings.Split(cliCtx.String(flags.GRPCHeadersFlag.Name), ","),
|
||||
BeaconNodeGRPCEndpoint: cliCtx.String(flags.BeaconRPCProviderFlag.Name),
|
||||
BeaconApiEndpoint: cliCtx.String(flags.BeaconRESTApiProviderFlag.Name),
|
||||
BeaconApiTimeout: time.Second * 30,
|
||||
BeaconNodeCert: c.cliCtx.String(flags.CertFlag.Name),
|
||||
BeaconNodeCert: cliCtx.String(flags.CertFlag.Name),
|
||||
DB: c.db,
|
||||
Wallet: c.wallet,
|
||||
WalletDir: walletDir,
|
||||
@@ -619,7 +567,8 @@ func (c *ValidatorClient) registerRPCService(router *http.ServeMux) error {
|
||||
ValidatorService: vs,
|
||||
AuthTokenPath: authTokenPath,
|
||||
Middlewares: middlewares,
|
||||
Router: router,
|
||||
Router: http.NewServeMux(),
|
||||
ServeWebUI: serveWebUI,
|
||||
})
|
||||
return c.services.RegisterService(s)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func CreateAuthToken(authPath, validatorWebAddr string) error {
|
||||
if err := saveAuthToken(authPath, token); err != nil {
|
||||
return err
|
||||
}
|
||||
logValidatorWebAuth(validatorWebAddr, token, authPath)
|
||||
logValidatorWebAuth(true, validatorWebAddr, token, authPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (s *Server) refreshAuthTokenFromFileChanges(ctx context.Context, authTokenP
|
||||
continue
|
||||
}
|
||||
validatorWebAddr := fmt.Sprintf("%s:%d", s.httpHost, s.httpPort)
|
||||
logValidatorWebAuth(validatorWebAddr, s.authToken, authTokenPath)
|
||||
logValidatorWebAuth(s.serveWebUI, validatorWebAddr, s.authToken, authTokenPath)
|
||||
case err := <-watcher.Errors:
|
||||
log.WithError(err).Errorf("Could not watch for file changes for: %s", authTokenPath)
|
||||
case <-ctx.Done():
|
||||
@@ -114,18 +114,19 @@ func (s *Server) refreshAuthTokenFromFileChanges(ctx context.Context, authTokenP
|
||||
}
|
||||
}
|
||||
|
||||
func logValidatorWebAuth(validatorWebAddr, token, tokenPath string) {
|
||||
webAuthURLTemplate := "http://%s/initialize?token=%s"
|
||||
webAuthURL := fmt.Sprintf(
|
||||
webAuthURLTemplate,
|
||||
validatorWebAddr,
|
||||
url.QueryEscape(token),
|
||||
)
|
||||
log.Infof(
|
||||
"Once your validator process is running, navigate to the link below to authenticate with " +
|
||||
"the Prysm web interface",
|
||||
)
|
||||
log.Info(webAuthURL)
|
||||
func logValidatorWebAuth(useWeb bool, validatorWebAddr, token, tokenPath string) {
|
||||
if useWeb {
|
||||
webAuthURLTemplate := "http://%s/initialize?token=%s"
|
||||
webAuthURL := fmt.Sprintf(
|
||||
webAuthURLTemplate,
|
||||
validatorWebAddr,
|
||||
url.QueryEscape(token),
|
||||
)
|
||||
log.Infof(
|
||||
"Starting Prysm WebUI, once your validator process is running, navigate to the link below to authenticate",
|
||||
)
|
||||
log.Info(webAuthURL)
|
||||
}
|
||||
log.Infof("Validator Client auth token for gRPC and REST authentication set at %s", tokenPath)
|
||||
}
|
||||
|
||||
|
||||
@@ -43,40 +43,42 @@ type Config struct {
|
||||
AuthTokenPath string
|
||||
Middlewares []middleware.Middleware
|
||||
Router *http.ServeMux
|
||||
ServeWebUI bool
|
||||
}
|
||||
|
||||
// Server defining a HTTP server for the remote signer API and registering clients
|
||||
type Server struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
httpHost string
|
||||
httpPort int
|
||||
server *httprest.Server
|
||||
serveWebUI bool
|
||||
walletInitialized bool
|
||||
logStreamerBufferSize int
|
||||
grpcMaxCallRecvMsgSize int
|
||||
walletInitializedFeed *event.Feed
|
||||
beaconApiTimeout time.Duration
|
||||
wallet *wallet.Wallet
|
||||
validatorService *client.ValidatorService
|
||||
httpPort int
|
||||
cancel context.CancelFunc
|
||||
grpcRetries uint
|
||||
grpcRetryDelay time.Duration
|
||||
grpcHeaders []string
|
||||
beaconNodeValidatorClient iface.ValidatorClient
|
||||
chainClient iface.ChainClient
|
||||
nodeClient iface.NodeClient
|
||||
healthClient ethpb.HealthClient
|
||||
beaconNodeEndpoint string
|
||||
beaconApiEndpoint string
|
||||
beaconApiTimeout time.Duration
|
||||
beaconNodeCert string
|
||||
jwtSecret []byte
|
||||
server *httprest.Server
|
||||
router *http.ServeMux
|
||||
authTokenPath string
|
||||
beaconNodeCert string
|
||||
beaconApiEndpoint string
|
||||
beaconNodeEndpoint string
|
||||
healthClient ethpb.HealthClient
|
||||
nodeClient iface.NodeClient
|
||||
chainClient iface.ChainClient
|
||||
beaconNodeValidatorClient iface.ValidatorClient
|
||||
httpHost string
|
||||
authToken string
|
||||
db db.Database
|
||||
walletDir string
|
||||
wallet *wallet.Wallet
|
||||
walletInitializedFeed *event.Feed
|
||||
walletInitialized bool
|
||||
validatorService *client.ValidatorService
|
||||
router *http.ServeMux
|
||||
logStreamer logs.Streamer
|
||||
logStreamerBufferSize int
|
||||
startFailure error
|
||||
ctx context.Context
|
||||
walletDir string
|
||||
jwtSecret []byte
|
||||
grpcHeaders []string
|
||||
}
|
||||
|
||||
// NewServer instantiates a new HTTP server.
|
||||
@@ -104,9 +106,11 @@ func NewServer(ctx context.Context, cfg *Config) *Server {
|
||||
beaconApiEndpoint: cfg.BeaconApiEndpoint,
|
||||
beaconNodeEndpoint: cfg.BeaconNodeGRPCEndpoint,
|
||||
router: cfg.Router,
|
||||
serveWebUI: cfg.ServeWebUI,
|
||||
}
|
||||
|
||||
if server.authTokenPath == "" && server.walletDir != "" {
|
||||
// if a wallet dir is passed without an auth token then override the default with the wallet dir
|
||||
server.authTokenPath = filepath.Join(server.walletDir, api.AuthTokenFileName)
|
||||
}
|
||||
|
||||
@@ -115,9 +119,10 @@ func NewServer(ctx context.Context, cfg *Config) *Server {
|
||||
log.WithError(err).Error("Could not initialize web auth token")
|
||||
}
|
||||
validatorWebAddr := fmt.Sprintf("%s:%d", server.httpHost, server.httpPort)
|
||||
logValidatorWebAuth(validatorWebAddr, server.authToken, server.authTokenPath)
|
||||
logValidatorWebAuth(server.serveWebUI, validatorWebAddr, server.authToken, server.authTokenPath)
|
||||
go server.refreshAuthTokenFromFileChanges(server.ctx, server.authTokenPath)
|
||||
}
|
||||
|
||||
// Register a gRPC or HTTP client to the beacon node.
|
||||
// Used for proxy calls to beacon node from validator REST handlers
|
||||
if err := server.registerBeaconClient(); err != nil {
|
||||
@@ -159,8 +164,9 @@ func (s *Server) InitializeRoutesWithWebHandler() error {
|
||||
if strings.HasPrefix(r.URL.Path, "/api") {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/api", "", 1) // used to redirect apis to standard rest APIs
|
||||
s.router.ServeHTTP(w, r)
|
||||
} else {
|
||||
// Finally, we handle with the web server.
|
||||
return
|
||||
}
|
||||
if s.serveWebUI {
|
||||
web.Handler(w, r)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user