mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 20:43:57 -05:00
Remove keystore keymanager from validator (#5236)
* Remove keystore keymanager from validator * Update dependency * Update validator/flags/flags.go * Update validator/flags/flags.go Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
This commit is contained in:
@@ -15,7 +15,7 @@ var (
|
||||
// DataDirFlag defines a path on disk.
|
||||
DataDirFlag = &cli.StringFlag{
|
||||
Name: "datadir",
|
||||
Usage: "Data directory for the databases and keystore",
|
||||
Usage: "Data directory for the databases",
|
||||
Value: DefaultDataDir(),
|
||||
}
|
||||
// EnableTracingFlag defines a flag to enable p2p message tracing.
|
||||
|
||||
@@ -17,9 +17,7 @@ go_library(
|
||||
"//shared/debug:go_default_library",
|
||||
"//shared/featureconfig:go_default_library",
|
||||
"//shared/logutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/version:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/flags:go_default_library",
|
||||
"//validator/node:go_default_library",
|
||||
"@com_github_joonix_log//:go_default_library",
|
||||
@@ -52,7 +50,6 @@ go_image(
|
||||
"//shared/logutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/version:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/flags:go_default_library",
|
||||
"//validator/node:go_default_library",
|
||||
"@com_github_joonix_log//:go_default_library",
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["account.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/validator/accounts",
|
||||
visibility = [
|
||||
"//validator:__pkg__",
|
||||
"//validator:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//contracts/deposit-contract:go_default_library",
|
||||
"//shared/keystore:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_x_crypto//ssh/terminal:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = ["account_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//shared/keystore:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,159 +0,0 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
contract "github.com/prysmaticlabs/prysm/contracts/deposit-contract"
|
||||
"github.com/prysmaticlabs/prysm/shared/keystore"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "accounts")
|
||||
|
||||
// DecryptKeysFromKeystore extracts a set of validator private keys from
|
||||
// an encrypted keystore directory and a password string.
|
||||
func DecryptKeysFromKeystore(directory string, password string) (map[string]*keystore.Key, error) {
|
||||
validatorPrefix := params.BeaconConfig().ValidatorPrivkeyFileName
|
||||
ks := keystore.NewKeystore(directory)
|
||||
validatorKeys, err := ks.GetKeys(directory, validatorPrefix, password, true /* warnOnFail */)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get private key")
|
||||
}
|
||||
return validatorKeys, nil
|
||||
}
|
||||
|
||||
// VerifyAccountNotExists checks if a validator has not yet created an account
|
||||
// and keystore in the provided directory string.
|
||||
func VerifyAccountNotExists(directory string, password string) error {
|
||||
if directory == "" || password == "" {
|
||||
return errors.New("expected a path to the validator keystore and password to be provided, received nil")
|
||||
}
|
||||
shardWithdrawalKeyFile := params.BeaconConfig().WithdrawalPrivkeyFileName
|
||||
validatorKeyFile := params.BeaconConfig().ValidatorPrivkeyFileName
|
||||
// First, if the keystore already exists, throws an error as there can only be
|
||||
// one keystore per validator client.
|
||||
ks := keystore.NewKeystore(directory)
|
||||
if _, err := ks.GetKeys(directory, shardWithdrawalKeyFile, password, false /* warnOnFail */); err == nil {
|
||||
return fmt.Errorf("keystore at path already exists: %s", shardWithdrawalKeyFile)
|
||||
}
|
||||
if _, err := ks.GetKeys(directory, validatorKeyFile, password, false /* warnOnFail */); err == nil {
|
||||
return fmt.Errorf("keystore at path already exists: %s", validatorKeyFile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewValidatorAccount sets up a validator client's secrets and generates the necessary deposit data
|
||||
// parameters needed to deposit into the deposit contract on the ETH1.0 chain. Specifically, this
|
||||
// generates a BLS private and public key, and then logs the serialized deposit input hex string
|
||||
// to be used in an ETH1.0 transaction by the validator.
|
||||
func NewValidatorAccount(directory string, password string) error {
|
||||
shardWithdrawalKeyFile := directory + params.BeaconConfig().WithdrawalPrivkeyFileName
|
||||
validatorKeyFile := directory + params.BeaconConfig().ValidatorPrivkeyFileName
|
||||
ks := keystore.NewKeystore(directory)
|
||||
// If the keystore does not exists at the path, we create a new one for the validator.
|
||||
shardWithdrawalKey, err := keystore.NewKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
shardWithdrawalKeyFile = shardWithdrawalKeyFile + hex.EncodeToString(shardWithdrawalKey.PublicKey.Marshal())[:12]
|
||||
if err := ks.StoreKey(shardWithdrawalKeyFile, shardWithdrawalKey, password); err != nil {
|
||||
return errors.Wrap(err, "unable to store key")
|
||||
}
|
||||
log.WithField(
|
||||
"path",
|
||||
shardWithdrawalKeyFile,
|
||||
).Info("Keystore generated for shard withdrawals at path")
|
||||
validatorKey, err := keystore.NewKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
validatorKeyFile = validatorKeyFile + hex.EncodeToString(validatorKey.PublicKey.Marshal())[:12]
|
||||
if err := ks.StoreKey(validatorKeyFile, validatorKey, password); err != nil {
|
||||
return errors.Wrap(err, "unable to store key")
|
||||
}
|
||||
log.WithField(
|
||||
"path",
|
||||
validatorKeyFile,
|
||||
).Info("Keystore generated for validator signatures at path")
|
||||
|
||||
data, depositRoot, err := keystore.DepositInput(validatorKey, shardWithdrawalKey, params.BeaconConfig().MaxEffectiveBalance)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to generate deposit data")
|
||||
}
|
||||
testAcc, err := contract.Setup()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to create simulated backend")
|
||||
}
|
||||
testAcc.TxOpts.GasLimit = 1000000
|
||||
|
||||
tx, err := testAcc.Contract.Deposit(testAcc.TxOpts, data.PublicKey, data.WithdrawalCredentials, data.Signature, depositRoot)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to create deposit transaction")
|
||||
}
|
||||
log.Info(`Account creation complete! Copy and paste the raw transaction data shown below when issuing a transaction into the ETH1.0 deposit contract to activate your validator client`)
|
||||
fmt.Printf(`
|
||||
========================Raw Transaction Data=======================
|
||||
|
||||
%#x
|
||||
|
||||
===================================================================
|
||||
`, tx.Data())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exists checks if a validator account at a given keystore path exists.
|
||||
func Exists(keystorePath string) (bool, error) {
|
||||
/* #nosec */
|
||||
f, err := os.Open(keystorePath)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = f.Readdirnames(1) // Or f.Readdir(1)
|
||||
if err == io.EOF {
|
||||
return false, nil
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
|
||||
// CreateValidatorAccount creates a validator account from the given cli context.
|
||||
func CreateValidatorAccount(path string, passphrase string) (string, string, error) {
|
||||
if passphrase == "" {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
log.Info("Create a new validator account for eth2")
|
||||
log.Info("Enter a password:")
|
||||
bytePassword, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
log.Fatalf("Could not read account password: %v", err)
|
||||
}
|
||||
text := string(bytePassword)
|
||||
passphrase = strings.Replace(text, "\n", "", -1)
|
||||
log.Infof("Keystore path to save your private keys (leave blank for default %s):", path)
|
||||
text, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
text = strings.Replace(text, "\n", "", -1)
|
||||
if text != "" {
|
||||
path = text
|
||||
}
|
||||
}
|
||||
|
||||
if err := NewValidatorAccount(path, passphrase); err != nil {
|
||||
return "", "", errors.Wrapf(err, "could not initialize validator account")
|
||||
}
|
||||
return path, passphrase, nil
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/keystore"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestNewValidatorAccount_AccountExists(t *testing.T) {
|
||||
directory := testutil.TempDir() + "/testkeystore"
|
||||
defer os.RemoveAll(directory)
|
||||
validatorKey, err := keystore.NewKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot create new key: %v", err)
|
||||
}
|
||||
ks := keystore.NewKeystore(directory)
|
||||
if err := ks.StoreKey(directory+params.BeaconConfig().ValidatorPrivkeyFileName, validatorKey, ""); err != nil {
|
||||
t.Fatalf("Unable to store key %v", err)
|
||||
}
|
||||
if err := NewValidatorAccount(directory, ""); err != nil {
|
||||
t.Errorf("Should support multiple keys: %v", err)
|
||||
}
|
||||
files, _ := ioutil.ReadDir(directory)
|
||||
if len(files) != 3 {
|
||||
t.Errorf("multiple validators were not created only %v files in directory", len(files))
|
||||
for _, f := range files {
|
||||
t.Errorf("%v\n", f.Name())
|
||||
}
|
||||
}
|
||||
if err := os.RemoveAll(directory); err != nil {
|
||||
t.Fatalf("Could not remove directory: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -73,12 +73,10 @@ go_test(
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/featureconfig:go_default_library",
|
||||
"//shared/keystore:go_default_library",
|
||||
"//shared/mock:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/roughtime:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/db:go_default_library",
|
||||
"//validator/internal:go_default_library",
|
||||
"//validator/keymanager:go_default_library",
|
||||
|
||||
@@ -9,48 +9,44 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/keystore"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"github.com/prysmaticlabs/prysm/validator/keymanager"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
var _ = shared.Service(&ValidatorService{})
|
||||
var validatorKey *keystore.Key
|
||||
var validatorPubKey [48]byte
|
||||
var keyMap map[[48]byte]*keystore.Key
|
||||
var keyMapThreeValidators map[[48]byte]*keystore.Key
|
||||
var validatorPubKey *bls.PublicKey
|
||||
var secKeyMap map[[48]byte]*bls.SecretKey
|
||||
var pubKeyMap map[[48]byte]*bls.PublicKey
|
||||
var secKeyMapThreeValidators map[[48]byte]*bls.SecretKey
|
||||
var pubKeyMapThreeValidators map[[48]byte]*bls.PublicKey
|
||||
var testKeyManager keymanager.KeyManager
|
||||
var testKeyManagerThreeValidators keymanager.KeyManager
|
||||
|
||||
func keySetup() {
|
||||
keyMap = make(map[[48]byte]*keystore.Key)
|
||||
keyMapThreeValidators = make(map[[48]byte]*keystore.Key)
|
||||
|
||||
validatorKey, _ = keystore.NewKey()
|
||||
copy(validatorPubKey[:], validatorKey.PublicKey.Marshal())
|
||||
keyMap[validatorPubKey] = validatorKey
|
||||
pubKeyMap = make(map[[48]byte]*bls.PublicKey)
|
||||
secKeyMap = make(map[[48]byte]*bls.SecretKey)
|
||||
pubKeyMapThreeValidators = make(map[[48]byte]*bls.PublicKey)
|
||||
secKeyMapThreeValidators = make(map[[48]byte]*bls.SecretKey)
|
||||
|
||||
sks := make([]*bls.SecretKey, 1)
|
||||
sks[0] = validatorKey.SecretKey
|
||||
sks[0] = bls.RandKey()
|
||||
testKeyManager = keymanager.NewDirect(sks)
|
||||
validatorPubKey = sks[0].PublicKey()
|
||||
|
||||
sks = make([]*bls.SecretKey, 3)
|
||||
for i := 0; i < 3; i++ {
|
||||
vKey, _ := keystore.NewKey()
|
||||
secKey := bls.RandKey()
|
||||
var pubKey [48]byte
|
||||
copy(pubKey[:], vKey.PublicKey.Marshal())
|
||||
keyMapThreeValidators[pubKey] = vKey
|
||||
sks[i] = vKey.SecretKey
|
||||
copy(pubKey[:], secKey.PublicKey().Marshal())
|
||||
secKeyMapThreeValidators[pubKey] = secKey
|
||||
pubKeyMapThreeValidators[pubKey] = secKey.PublicKey()
|
||||
sks[i] = secKey
|
||||
}
|
||||
testKeyManagerThreeValidators = keymanager.NewDirect(sks)
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
dir := testutil.TempDir() + "/keystore1"
|
||||
defer os.RemoveAll(dir)
|
||||
accounts.NewValidatorAccount(dir, "1234")
|
||||
keySetup()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
@@ -18,7 +19,7 @@ func TestSubmitAggregateAndProof_GetDutiesRequestFailure(t *testing.T) {
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
|
||||
defer finish()
|
||||
|
||||
validator.SubmitAggregateAndProof(context.Background(), 0, validatorPubKey)
|
||||
validator.SubmitAggregateAndProof(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Could not fetch validator assignment")
|
||||
}
|
||||
@@ -29,7 +30,7 @@ func TestSubmitAggregateAndProof_Ok(t *testing.T) {
|
||||
validator.duties = ðpb.DutiesResponse{
|
||||
Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -60,7 +61,7 @@ func TestSubmitAggregateAndProof_Ok(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.SignedAggregateSubmitRequest{}),
|
||||
).Return(ðpb.SignedAggregateSubmitResponse{}, nil)
|
||||
|
||||
validator.SubmitAggregateAndProof(context.Background(), 0, validatorPubKey)
|
||||
validator.SubmitAggregateAndProof(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
}
|
||||
|
||||
func TestWaitForSlotTwoThird_WaitCorrectly(t *testing.T) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/roughtime"
|
||||
@@ -27,7 +28,7 @@ func TestRequestAttestation_ValidatorDutiesRequestFailure(t *testing.T) {
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
|
||||
defer finish()
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Could not fetch validator assignment")
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestAttestToBlockHead_SubmitAttestationRequestFailure(t *testing.T) {
|
||||
defer finish()
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: make([]uint64, 111),
|
||||
ValidatorIndex: 0,
|
||||
@@ -60,7 +61,7 @@ func TestAttestToBlockHead_SubmitAttestationRequestFailure(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.Attestation{}),
|
||||
).Return(nil, errors.New("something went wrong"))
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Could not submit attestation to beacon node")
|
||||
}
|
||||
|
||||
@@ -71,7 +72,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -98,7 +99,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
|
||||
generatedAttestation = att
|
||||
}).Return(ðpb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
aggregationBitfield := bitfield.NewBitlist(uint64(len(committee)))
|
||||
aggregationBitfield.SetBitAt(4, true)
|
||||
@@ -116,7 +117,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sig, err := validator.keyManager.Sign(validatorPubKey, root)
|
||||
sig, err := validator.keyManager.Sign(bytesutil.ToBytes48(validatorPubKey.Marshal()), root)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -140,7 +141,7 @@ func TestAttestToBlockHead_BlocksDoubleAtt(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -164,8 +165,8 @@ func TestAttestToBlockHead_BlocksDoubleAtt(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.Attestation{}),
|
||||
).Return(ðpb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Attempted to make a slashable attestation, rejected")
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ func TestAttestToBlockHead_BlocksSurroundAtt(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -205,7 +206,7 @@ func TestAttestToBlockHead_BlocksSurroundAtt(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.Attestation{}),
|
||||
).Return(ðpb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
m.validatorClient.EXPECT().GetAttestationData(
|
||||
gomock.Any(), // ctx
|
||||
@@ -216,7 +217,7 @@ func TestAttestToBlockHead_BlocksSurroundAtt(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{Root: []byte("C"), Epoch: 0},
|
||||
}, nil)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Attempted to make a slashable attestation, rejected")
|
||||
}
|
||||
|
||||
@@ -232,7 +233,7 @@ func TestAttestToBlockHead_BlocksSurroundedAtt(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -256,7 +257,7 @@ func TestAttestToBlockHead_BlocksSurroundedAtt(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.Attestation{}),
|
||||
).Return(ðpb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
m.validatorClient.EXPECT().GetAttestationData(
|
||||
gomock.Any(), // ctx
|
||||
@@ -267,7 +268,7 @@ func TestAttestToBlockHead_BlocksSurroundedAtt(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{Root: []byte("C"), Epoch: 1},
|
||||
}, nil)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Attempted to make a slashable attestation, rejected")
|
||||
}
|
||||
|
||||
@@ -293,7 +294,7 @@ func TestAttestToBlockHead_DoesNotAttestBeforeDelay(t *testing.T) {
|
||||
).Return(ðpb.AttestResponse{}, nil /* error */).Times(0)
|
||||
|
||||
timer := time.NewTimer(1 * time.Second)
|
||||
go validator.SubmitAttestation(context.Background(), 0, validatorPubKey)
|
||||
go validator.SubmitAttestation(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
<-timer.C
|
||||
}
|
||||
|
||||
@@ -310,7 +311,7 @@ func TestAttestToBlockHead_DoesAttestAfterDelay(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -337,7 +338,7 @@ func TestAttestToBlockHead_DoesAttestAfterDelay(t *testing.T) {
|
||||
gomock.Any(),
|
||||
).Return(ðpb.AttestResponse{}, nil).Times(1)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 0, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_CorrectBitfieldLength(t *testing.T) {
|
||||
@@ -347,7 +348,7 @@ func TestAttestToBlockHead_CorrectBitfieldLength(t *testing.T) {
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
validator.duties = ðpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
PublicKey: validatorKey.PublicKey.Marshal(),
|
||||
PublicKey: validatorPubKey.Marshal(),
|
||||
CommitteeIndex: 5,
|
||||
Committee: committee,
|
||||
ValidatorIndex: validatorIndex,
|
||||
@@ -373,7 +374,7 @@ func TestAttestToBlockHead_CorrectBitfieldLength(t *testing.T) {
|
||||
generatedAttestation = att
|
||||
}).Return(ðpb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.SubmitAttestation(context.Background(), 30, validatorPubKey)
|
||||
validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
if len(generatedAttestation.AggregationBits) != 2 {
|
||||
t.Errorf("Wanted length %d, received %d", 2, len(generatedAttestation.AggregationBits))
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
@@ -22,7 +23,7 @@ type mocks struct {
|
||||
}
|
||||
|
||||
func setup(t *testing.T) (*validator, *mocks, func()) {
|
||||
valDB := db.SetupDB(t, [][48]byte{validatorPubKey})
|
||||
valDB := db.SetupDB(t, [][48]byte{bytesutil.ToBytes48(validatorPubKey.Marshal())})
|
||||
ctrl := gomock.NewController(t)
|
||||
m := &mocks{
|
||||
validatorClient: internal.NewMockBeaconNodeValidatorClient(ctrl),
|
||||
@@ -42,7 +43,7 @@ func TestProposeBlock_DoesNotProposeGenesisBlock(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
validator, _, finish := setup(t)
|
||||
defer finish()
|
||||
validator.ProposeBlock(context.Background(), 0, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Assigned to genesis slot, skipping proposal")
|
||||
}
|
||||
@@ -57,7 +58,7 @@ func TestProposeBlock_DomainDataFailed(t *testing.T) {
|
||||
gomock.Any(), // epoch
|
||||
).Return(nil /*response*/, errors.New("uh oh"))
|
||||
|
||||
validator.ProposeBlock(context.Background(), 1, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 1, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Failed to sign randao reveal")
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ func TestProposeBlock_RequestBlockFailed(t *testing.T) {
|
||||
gomock.Any(), // block request
|
||||
).Return(nil /*response*/, errors.New("uh oh"))
|
||||
|
||||
validator.ProposeBlock(context.Background(), 1, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 1, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Failed to request block from beacon node")
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ func TestProposeBlock_ProposeBlockFailed(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.SignedBeaconBlock{}),
|
||||
).Return(nil /*response*/, errors.New("uh oh"))
|
||||
|
||||
validator.ProposeBlock(context.Background(), 1, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 1, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Failed to propose block")
|
||||
}
|
||||
|
||||
@@ -139,10 +140,10 @@ func TestProposeBlock_BlocksDoubleProposal(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.SignedBeaconBlock{}),
|
||||
).Return(ðpb.ProposeResponse{}, nil /*error*/)
|
||||
|
||||
validator.ProposeBlock(context.Background(), params.BeaconConfig().SlotsPerEpoch*5+2, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), params.BeaconConfig().SlotsPerEpoch*5+2, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
|
||||
|
||||
validator.ProposeBlock(context.Background(), params.BeaconConfig().SlotsPerEpoch*5+2, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), params.BeaconConfig().SlotsPerEpoch*5+2, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Tried to sign a double proposal")
|
||||
}
|
||||
|
||||
@@ -177,10 +178,10 @@ func TestProposeBlock_BlocksDoubleProposal_After54KEpochs(t *testing.T) {
|
||||
).Return(ðpb.ProposeResponse{}, nil /*error*/)
|
||||
|
||||
farFuture := (params.BeaconConfig().WeakSubjectivityPeriod + 9) * params.BeaconConfig().SlotsPerEpoch
|
||||
validator.ProposeBlock(context.Background(), farFuture, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), farFuture, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
|
||||
|
||||
validator.ProposeBlock(context.Background(), farFuture, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), farFuture, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsContain(t, hook, "Tried to sign a double proposal")
|
||||
}
|
||||
|
||||
@@ -215,11 +216,11 @@ func TestProposeBlock_AllowsPastProposals(t *testing.T) {
|
||||
).Times(2).Return(ðpb.ProposeResponse{}, nil /*error*/)
|
||||
|
||||
farAhead := (params.BeaconConfig().WeakSubjectivityPeriod + 9) * params.BeaconConfig().SlotsPerEpoch
|
||||
validator.ProposeBlock(context.Background(), farAhead, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), farAhead, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
|
||||
|
||||
past := (params.BeaconConfig().WeakSubjectivityPeriod - 400) * params.BeaconConfig().SlotsPerEpoch
|
||||
validator.ProposeBlock(context.Background(), past, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), past, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ func TestProposeBlock_BroadcastsBlock(t *testing.T) {
|
||||
gomock.AssignableToTypeOf(ðpb.SignedBeaconBlock{}),
|
||||
).Return(ðpb.ProposeResponse{}, nil /*error*/)
|
||||
|
||||
validator.ProposeBlock(context.Background(), 1, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 1, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
}
|
||||
|
||||
func TestProposeBlock_BroadcastsBlock_WithGraffiti(t *testing.T) {
|
||||
@@ -281,7 +282,7 @@ func TestProposeBlock_BroadcastsBlock_WithGraffiti(t *testing.T) {
|
||||
return ðpb.ProposeResponse{}, nil
|
||||
})
|
||||
|
||||
validator.ProposeBlock(context.Background(), 1, validatorPubKey)
|
||||
validator.ProposeBlock(context.Background(), 1, bytesutil.ToBytes48(validatorPubKey.Marshal()))
|
||||
|
||||
if string(sentBlock.Block.Body.Graffiti) != string(validator.graffiti) {
|
||||
t.Errorf("Block was broadcast with the wrong graffiti field, wanted \"%v\", got \"%v\"", string(validator.graffiti), string(sentBlock.Block.Body.Graffiti))
|
||||
|
||||
@@ -21,22 +21,17 @@ var (
|
||||
Name: "tls-cert",
|
||||
Usage: "Certificate for secure gRPC. Pass this and the tls-key flag in order to use gRPC securely.",
|
||||
}
|
||||
// KeystorePathFlag defines the location of the keystore directory for a validator's account.
|
||||
KeystorePathFlag = &cli.StringFlag{
|
||||
Name: "keystore-path",
|
||||
Usage: "Path to the desired keystore directory",
|
||||
}
|
||||
// UnencryptedKeysFlag specifies a file path of a JSON file of unencrypted validator keys as an
|
||||
// alternative from launching the validator client from decrypting a keystore directory.
|
||||
// UnencryptedKeysFlag specifies a file path of a JSON file of unencrypted validator keys; this should only
|
||||
// be used for test networks.
|
||||
UnencryptedKeysFlag = &cli.StringFlag{
|
||||
Name: "unencrypted-keys",
|
||||
Usage: "Filepath to a JSON file of unencrypted validator keys for easier launching of the validator client",
|
||||
Usage: "Filepath to a JSON file of unencrypted validator keys for launching the validator client on test networks",
|
||||
Value: "",
|
||||
}
|
||||
// KeyManager specifies the key manager to use.
|
||||
KeyManager = &cli.StringFlag{
|
||||
Name: "keymanager",
|
||||
Usage: "The keymanger to use (unencrypted, interop, keystore, wallet)",
|
||||
Usage: "For specifying the keymanager to use (remote, wallet, unencrypted, interop)",
|
||||
Value: "",
|
||||
}
|
||||
// KeyManagerOpts specifies the key manager options.
|
||||
@@ -45,11 +40,6 @@ var (
|
||||
Usage: "The options for the keymanger, either a JSON string or path to same",
|
||||
Value: "",
|
||||
}
|
||||
// PasswordFlag defines the password value for storing and retrieving validator private keys from the keystore.
|
||||
PasswordFlag = &cli.StringFlag{
|
||||
Name: "password",
|
||||
Usage: "String value of the password for your validator private keys",
|
||||
}
|
||||
// DisablePenaltyRewardLogFlag defines the ability to not log reward/penalty information during deployment
|
||||
DisablePenaltyRewardLogFlag = &cli.BoolFlag{
|
||||
Name: "disable-rewards-penalties-logging",
|
||||
|
||||
@@ -5,7 +5,6 @@ go_library(
|
||||
srcs = [
|
||||
"direct.go",
|
||||
"direct_interop.go",
|
||||
"direct_keystore.go",
|
||||
"direct_unencrypted.go",
|
||||
"keymanager.go",
|
||||
"log.go",
|
||||
@@ -19,7 +18,6 @@ go_library(
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/interop:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
@@ -29,7 +27,6 @@ go_library(
|
||||
"@com_github_wealdtech_go_eth2_wallet_types_v2//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//credentials:go_default_library",
|
||||
"@org_golang_x_crypto//ssh/terminal:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
package keymanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
// Keystore is a key manager that loads keys from a standard keystore.
|
||||
type Keystore struct {
|
||||
*Direct
|
||||
}
|
||||
|
||||
type keystoreOpts struct {
|
||||
Path string `json:"path"`
|
||||
Passphrase string `json:"passphrase"`
|
||||
}
|
||||
|
||||
var keystoreOptsHelp = `The keystore key manager generates keys and stores them in a local encrypted store. The options are:
|
||||
- path This is the filesystem path to where keys will be stored. Defaults to the user's home directory if not supplied
|
||||
- passphrase This is the passphrase used to encrypt keys. Will be asked for if not supplied
|
||||
A sample set of options are:
|
||||
{
|
||||
"path": "/home/me/keys", // Store the keys in '/home/me/keys'
|
||||
"passphrase": "secret" // Use the passphrase 'secret' to encrypt and decrypt keys
|
||||
}`
|
||||
|
||||
// NewKeystore creates a key manager populated with the keys from the keystore at the given path.
|
||||
func NewKeystore(input string) (KeyManager, string, error) {
|
||||
opts := &keystoreOpts{}
|
||||
err := json.Unmarshal([]byte(input), opts)
|
||||
if err != nil {
|
||||
return nil, keystoreOptsHelp, err
|
||||
}
|
||||
|
||||
if strings.Contains(opts.Path, "$") || strings.Contains(opts.Path, "~") || strings.Contains(opts.Path, "%") {
|
||||
log.WithField("path", opts.Path).Warn("Keystore path contains unexpanded shell expansion characters")
|
||||
}
|
||||
|
||||
if opts.Path == "" {
|
||||
opts.Path = defaultValidatorDir()
|
||||
}
|
||||
|
||||
exists, err := accounts.Exists(opts.Path)
|
||||
if err != nil {
|
||||
return nil, keystoreOptsHelp, err
|
||||
}
|
||||
if !exists {
|
||||
// If an account does not exist, we create a new one and start the node.
|
||||
opts.Path, opts.Passphrase, err = accounts.CreateValidatorAccount(opts.Path, opts.Passphrase)
|
||||
if err != nil {
|
||||
return nil, keystoreOptsHelp, err
|
||||
}
|
||||
} else {
|
||||
if opts.Passphrase == "" {
|
||||
log.Info("Enter your validator account password:")
|
||||
bytePassword, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return nil, keystoreOptsHelp, err
|
||||
}
|
||||
text := string(bytePassword)
|
||||
opts.Passphrase = strings.Replace(text, "\n", "", -1)
|
||||
}
|
||||
|
||||
if err := accounts.VerifyAccountNotExists(opts.Path, opts.Passphrase); err == nil {
|
||||
log.Info("No account found, creating new validator account...")
|
||||
}
|
||||
}
|
||||
|
||||
keyMap, err := accounts.DecryptKeysFromKeystore(opts.Path, opts.Passphrase)
|
||||
if err != nil {
|
||||
return nil, keystoreOptsHelp, err
|
||||
}
|
||||
|
||||
km := &Unencrypted{
|
||||
Direct: &Direct{
|
||||
publicKeys: make(map[[48]byte]*bls.PublicKey),
|
||||
secretKeys: make(map[[48]byte]*bls.SecretKey),
|
||||
},
|
||||
}
|
||||
for _, key := range keyMap {
|
||||
pubKey := bytesutil.ToBytes48(key.PublicKey.Marshal())
|
||||
km.publicKeys[pubKey] = key.PublicKey
|
||||
km.secretKeys[pubKey] = key.SecretKey
|
||||
}
|
||||
return km, "", nil
|
||||
}
|
||||
|
||||
func homeDir() string {
|
||||
if home := os.Getenv("HOME"); home != "" {
|
||||
return home
|
||||
}
|
||||
if usr, err := user.Current(); err == nil {
|
||||
return usr.HomeDir
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultValidatorDir() string {
|
||||
// Try to place the data folder in the user's home dir
|
||||
home := homeDir()
|
||||
if home != "" {
|
||||
if runtime.GOOS == "darwin" {
|
||||
return filepath.Join(home, "Library", "Eth2Validators")
|
||||
} else if runtime.GOOS == "windows" {
|
||||
return filepath.Join(home, "AppData", "Roaming", "Eth2Validators")
|
||||
} else {
|
||||
return filepath.Join(home, ".eth2validators")
|
||||
}
|
||||
}
|
||||
// As we cannot guess a stable location, return empty and handle later
|
||||
return ""
|
||||
}
|
||||
@@ -11,9 +11,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/shared/debug"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/logutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/version"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"github.com/prysmaticlabs/prysm/validator/flags"
|
||||
"github.com/prysmaticlabs/prysm/validator/node"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -39,8 +37,6 @@ var appFlags = []cli.Flag{
|
||||
flags.BeaconRPCProviderFlag,
|
||||
flags.CertFlag,
|
||||
flags.GraffitiFlag,
|
||||
flags.KeystorePathFlag,
|
||||
flags.PasswordFlag,
|
||||
flags.DisablePenaltyRewardLogFlag,
|
||||
flags.UnencryptedKeysFlag,
|
||||
flags.InteropStartIndex,
|
||||
@@ -81,68 +77,6 @@ func main() {
|
||||
starts proposer services, shardp2p connections, and more`
|
||||
app.Version = version.GetVersion()
|
||||
app.Action = startNode
|
||||
app.Commands = []*cli.Command{
|
||||
{
|
||||
Name: "accounts",
|
||||
Category: "accounts",
|
||||
Usage: "defines useful functions for interacting with the validator client's account",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "create",
|
||||
Description: `creates a new validator account keystore containing private keys for Ethereum Serenity -
|
||||
this command outputs a deposit data string which can be used to deposit Ether into the ETH1.0 deposit
|
||||
contract in order to activate the validator client`,
|
||||
Flags: []cli.Flag{
|
||||
flags.KeystorePathFlag,
|
||||
flags.PasswordFlag,
|
||||
},
|
||||
Action: func(ctx *cli.Context) error {
|
||||
featureconfig.ConfigureValidator(ctx)
|
||||
// Use custom config values if the --no-custom-config flag is set.
|
||||
if !ctx.Bool(flags.NoCustomConfigFlag.Name) {
|
||||
log.Info("Using custom parameter configuration")
|
||||
if featureconfig.Get().MinimalConfig {
|
||||
log.Warn("Using Minimal Config")
|
||||
params.UseMinimalConfig()
|
||||
} else {
|
||||
log.Warn("Using Demo Config")
|
||||
params.UseDemoBeaconConfig()
|
||||
}
|
||||
}
|
||||
|
||||
if keystoreDir, _, err := accounts.CreateValidatorAccount(ctx.String(flags.KeystorePathFlag.Name), ctx.String(flags.PasswordFlag.Name)); err != nil {
|
||||
log.WithError(err).Fatalf("Could not create validator at path: %s", keystoreDir)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "keys",
|
||||
Description: `lists the private keys for 'keystore' keymanager keys`,
|
||||
Flags: []cli.Flag{
|
||||
flags.KeystorePathFlag,
|
||||
flags.PasswordFlag,
|
||||
},
|
||||
Action: func(ctx *cli.Context) error {
|
||||
if ctx.String(flags.KeystorePathFlag.Name) == "" {
|
||||
log.Fatalf("%s is required", flags.KeystorePathFlag.Name)
|
||||
}
|
||||
if ctx.String(flags.PasswordFlag.Name) == "" {
|
||||
log.Fatalf("%s is required", flags.PasswordFlag.Name)
|
||||
}
|
||||
keystores, err := accounts.DecryptKeysFromKeystore(ctx.String(flags.KeystorePathFlag.Name), ctx.String(flags.PasswordFlag.Name))
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("Failed to decrypt keystore keys at path %s", ctx.String(flags.KeystorePathFlag.Name))
|
||||
}
|
||||
for _, v := range keystores {
|
||||
fmt.Printf("Public key: %#x private key: %#x\n", v.PublicKey.Marshal(), v.SecretKey.Marshal())
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
app.Flags = appFlags
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
|
||||
@@ -7,7 +7,6 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"@in_gopkg_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -218,37 +218,25 @@ func selectKeyManager(ctx *cli.Context) (keymanager.KeyManager, error) {
|
||||
manager = "interop"
|
||||
opts = fmt.Sprintf(`{"keys":%d,"offset":%d}`, numValidatorKeys, ctx.Uint64(flags.InteropStartIndex.Name))
|
||||
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`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if manager == "" {
|
||||
return nil, fmt.Errorf("please supply a keymanager with --keymanager")
|
||||
}
|
||||
|
||||
var km keymanager.KeyManager
|
||||
var help string
|
||||
var err error
|
||||
switch manager {
|
||||
case "remote":
|
||||
km, help, err = keymanager.NewRemoteWallet(opts)
|
||||
case "wallet":
|
||||
km, help, err = keymanager.NewWallet(opts)
|
||||
case "interop":
|
||||
km, help, err = keymanager.NewInterop(opts)
|
||||
case "unencrypted":
|
||||
km, help, err = keymanager.NewUnencrypted(opts)
|
||||
case "keystore":
|
||||
km, help, err = keymanager.NewKeystore(opts)
|
||||
case "wallet":
|
||||
km, help, err = keymanager.NewWallet(opts)
|
||||
case "remote":
|
||||
km, help, err = keymanager.NewRemoteWallet(opts)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown keymanager %q", manager)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package node
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
@@ -14,18 +14,14 @@ import (
|
||||
func TestNode_Builds(t *testing.T) {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("datadir", testutil.TempDir()+"/datadir", "the node data directory")
|
||||
dir := testutil.TempDir() + "/keystore1"
|
||||
defer os.RemoveAll(dir)
|
||||
defer os.RemoveAll(testutil.TempDir() + "/datadir")
|
||||
set.String("keystore-path", dir, "path to keystore")
|
||||
set.String("password", "1234", "validator account password")
|
||||
tmpDir := testutil.TempDir()
|
||||
defer os.RemoveAll(tmpDir)
|
||||
set.String("datadir", filepath.Join(tmpDir, "datadir"), "the node data directory")
|
||||
set.String("keymanager", "interop", "key manager")
|
||||
set.String("keymanageropts", `{"keys":16,"offset":0}`, `key manager options`)
|
||||
set.String("verbosity", "debug", "log verbosity")
|
||||
context := cli.NewContext(&app, set, nil)
|
||||
|
||||
if err := accounts.NewValidatorAccount(dir, "1234"); err != nil {
|
||||
t.Fatalf("Could not create validator account: %v", err)
|
||||
}
|
||||
_, err := NewValidatorClient(context)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create ValidatorClient: %v", err)
|
||||
|
||||
@@ -77,8 +77,6 @@ var appHelpFlagGroups = []flagGroup{
|
||||
flags.CertFlag,
|
||||
flags.KeyManager,
|
||||
flags.KeyManagerOpts,
|
||||
flags.KeystorePathFlag,
|
||||
flags.PasswordFlag,
|
||||
flags.DisablePenaltyRewardLogFlag,
|
||||
flags.UnencryptedKeysFlag,
|
||||
flags.GraffitiFlag,
|
||||
|
||||
Reference in New Issue
Block a user