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:
Jim McDonald
2020-03-30 05:49:02 +01:00
committed by GitHub
parent b2375aeccf
commit 46008770c1
18 changed files with 74 additions and 526 deletions

View File

@@ -15,7 +15,7 @@ var (
// DataDirFlag defines a path on disk. // DataDirFlag defines a path on disk.
DataDirFlag = &cli.StringFlag{ DataDirFlag = &cli.StringFlag{
Name: "datadir", Name: "datadir",
Usage: "Data directory for the databases and keystore", Usage: "Data directory for the databases",
Value: DefaultDataDir(), Value: DefaultDataDir(),
} }
// EnableTracingFlag defines a flag to enable p2p message tracing. // EnableTracingFlag defines a flag to enable p2p message tracing.

View File

@@ -17,9 +17,7 @@ go_library(
"//shared/debug:go_default_library", "//shared/debug:go_default_library",
"//shared/featureconfig:go_default_library", "//shared/featureconfig:go_default_library",
"//shared/logutil:go_default_library", "//shared/logutil:go_default_library",
"//shared/params:go_default_library",
"//shared/version:go_default_library", "//shared/version:go_default_library",
"//validator/accounts:go_default_library",
"//validator/flags:go_default_library", "//validator/flags:go_default_library",
"//validator/node:go_default_library", "//validator/node:go_default_library",
"@com_github_joonix_log//:go_default_library", "@com_github_joonix_log//:go_default_library",
@@ -52,7 +50,6 @@ go_image(
"//shared/logutil:go_default_library", "//shared/logutil:go_default_library",
"//shared/params:go_default_library", "//shared/params:go_default_library",
"//shared/version:go_default_library", "//shared/version:go_default_library",
"//validator/accounts:go_default_library",
"//validator/flags:go_default_library", "//validator/flags:go_default_library",
"//validator/node:go_default_library", "//validator/node:go_default_library",
"@com_github_joonix_log//:go_default_library", "@com_github_joonix_log//:go_default_library",

View File

@@ -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",
],
)

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -73,12 +73,10 @@ go_test(
"//shared/bls:go_default_library", "//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library", "//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library", "//shared/featureconfig:go_default_library",
"//shared/keystore:go_default_library",
"//shared/mock:go_default_library", "//shared/mock:go_default_library",
"//shared/params:go_default_library", "//shared/params:go_default_library",
"//shared/roughtime:go_default_library", "//shared/roughtime:go_default_library",
"//shared/testutil:go_default_library", "//shared/testutil:go_default_library",
"//validator/accounts:go_default_library",
"//validator/db:go_default_library", "//validator/db:go_default_library",
"//validator/internal:go_default_library", "//validator/internal:go_default_library",
"//validator/keymanager:go_default_library", "//validator/keymanager:go_default_library",

View File

@@ -9,48 +9,44 @@ import (
"github.com/prysmaticlabs/prysm/shared" "github.com/prysmaticlabs/prysm/shared"
"github.com/prysmaticlabs/prysm/shared/bls" "github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/keystore"
"github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/keymanager" "github.com/prysmaticlabs/prysm/validator/keymanager"
logTest "github.com/sirupsen/logrus/hooks/test" logTest "github.com/sirupsen/logrus/hooks/test"
) )
var _ = shared.Service(&ValidatorService{}) var _ = shared.Service(&ValidatorService{})
var validatorKey *keystore.Key var validatorPubKey *bls.PublicKey
var validatorPubKey [48]byte var secKeyMap map[[48]byte]*bls.SecretKey
var keyMap map[[48]byte]*keystore.Key var pubKeyMap map[[48]byte]*bls.PublicKey
var keyMapThreeValidators map[[48]byte]*keystore.Key var secKeyMapThreeValidators map[[48]byte]*bls.SecretKey
var pubKeyMapThreeValidators map[[48]byte]*bls.PublicKey
var testKeyManager keymanager.KeyManager var testKeyManager keymanager.KeyManager
var testKeyManagerThreeValidators keymanager.KeyManager var testKeyManagerThreeValidators keymanager.KeyManager
func keySetup() { func keySetup() {
keyMap = make(map[[48]byte]*keystore.Key) pubKeyMap = make(map[[48]byte]*bls.PublicKey)
keyMapThreeValidators = make(map[[48]byte]*keystore.Key) secKeyMap = make(map[[48]byte]*bls.SecretKey)
pubKeyMapThreeValidators = make(map[[48]byte]*bls.PublicKey)
validatorKey, _ = keystore.NewKey() secKeyMapThreeValidators = make(map[[48]byte]*bls.SecretKey)
copy(validatorPubKey[:], validatorKey.PublicKey.Marshal())
keyMap[validatorPubKey] = validatorKey
sks := make([]*bls.SecretKey, 1) sks := make([]*bls.SecretKey, 1)
sks[0] = validatorKey.SecretKey sks[0] = bls.RandKey()
testKeyManager = keymanager.NewDirect(sks) testKeyManager = keymanager.NewDirect(sks)
validatorPubKey = sks[0].PublicKey()
sks = make([]*bls.SecretKey, 3) sks = make([]*bls.SecretKey, 3)
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
vKey, _ := keystore.NewKey() secKey := bls.RandKey()
var pubKey [48]byte var pubKey [48]byte
copy(pubKey[:], vKey.PublicKey.Marshal()) copy(pubKey[:], secKey.PublicKey().Marshal())
keyMapThreeValidators[pubKey] = vKey secKeyMapThreeValidators[pubKey] = secKey
sks[i] = vKey.SecretKey pubKeyMapThreeValidators[pubKey] = secKey.PublicKey()
sks[i] = secKey
} }
testKeyManagerThreeValidators = keymanager.NewDirect(sks) testKeyManagerThreeValidators = keymanager.NewDirect(sks)
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
dir := testutil.TempDir() + "/keystore1"
defer os.RemoveAll(dir)
accounts.NewValidatorAccount(dir, "1234")
keySetup() keySetup()
os.Exit(m.Run()) os.Exit(m.Run())
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil"
logTest "github.com/sirupsen/logrus/hooks/test" logTest "github.com/sirupsen/logrus/hooks/test"
@@ -18,7 +19,7 @@ func TestSubmitAggregateAndProof_GetDutiesRequestFailure(t *testing.T) {
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}} validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
defer finish() 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") testutil.AssertLogsContain(t, hook, "Could not fetch validator assignment")
} }
@@ -29,7 +30,7 @@ func TestSubmitAggregateAndProof_Ok(t *testing.T) {
validator.duties = &ethpb.DutiesResponse{ validator.duties = &ethpb.DutiesResponse{
Duties: []*ethpb.DutiesResponse_Duty{ Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
}, },
}, },
} }
@@ -60,7 +61,7 @@ func TestSubmitAggregateAndProof_Ok(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.SignedAggregateSubmitRequest{}), gomock.AssignableToTypeOf(&ethpb.SignedAggregateSubmitRequest{}),
).Return(&ethpb.SignedAggregateSubmitResponse{}, nil) ).Return(&ethpb.SignedAggregateSubmitResponse{}, nil)
validator.SubmitAggregateAndProof(context.Background(), 0, validatorPubKey) validator.SubmitAggregateAndProof(context.Background(), 0, bytesutil.ToBytes48(validatorPubKey.Marshal()))
} }
func TestWaitForSlotTwoThird_WaitCorrectly(t *testing.T) { func TestWaitForSlotTwoThird_WaitCorrectly(t *testing.T) {

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
slashpb "github.com/prysmaticlabs/prysm/proto/slashing" slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime" "github.com/prysmaticlabs/prysm/shared/roughtime"
@@ -27,7 +28,7 @@ func TestRequestAttestation_ValidatorDutiesRequestFailure(t *testing.T) {
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}} validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
defer finish() 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") testutil.AssertLogsContain(t, hook, "Could not fetch validator assignment")
} }
@@ -38,7 +39,7 @@ func TestAttestToBlockHead_SubmitAttestationRequestFailure(t *testing.T) {
defer finish() defer finish()
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: make([]uint64, 111), Committee: make([]uint64, 111),
ValidatorIndex: 0, ValidatorIndex: 0,
@@ -60,7 +61,7 @@ func TestAttestToBlockHead_SubmitAttestationRequestFailure(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.Attestation{}), gomock.AssignableToTypeOf(&ethpb.Attestation{}),
).Return(nil, errors.New("something went wrong")) ).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") 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} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -98,7 +99,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
generatedAttestation = att generatedAttestation = att
}).Return(&ethpb.AttestResponse{}, nil /* error */) }).Return(&ethpb.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 := bitfield.NewBitlist(uint64(len(committee)))
aggregationBitfield.SetBitAt(4, true) aggregationBitfield.SetBitAt(4, true)
@@ -116,7 +117,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
sig, err := validator.keyManager.Sign(validatorPubKey, root) sig, err := validator.keyManager.Sign(bytesutil.ToBytes48(validatorPubKey.Marshal()), root)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -140,7 +141,7 @@ func TestAttestToBlockHead_BlocksDoubleAtt(t *testing.T) {
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -164,8 +165,8 @@ func TestAttestToBlockHead_BlocksDoubleAtt(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.Attestation{}), gomock.AssignableToTypeOf(&ethpb.Attestation{}),
).Return(&ethpb.AttestResponse{}, nil /* error */) ).Return(&ethpb.AttestResponse{}, nil /* error */)
validator.SubmitAttestation(context.Background(), 30, validatorPubKey) validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
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") 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} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -205,7 +206,7 @@ func TestAttestToBlockHead_BlocksSurroundAtt(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.Attestation{}), gomock.AssignableToTypeOf(&ethpb.Attestation{}),
).Return(&ethpb.AttestResponse{}, nil /* error */) ).Return(&ethpb.AttestResponse{}, nil /* error */)
validator.SubmitAttestation(context.Background(), 30, validatorPubKey) validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
m.validatorClient.EXPECT().GetAttestationData( m.validatorClient.EXPECT().GetAttestationData(
gomock.Any(), // ctx gomock.Any(), // ctx
@@ -216,7 +217,7 @@ func TestAttestToBlockHead_BlocksSurroundAtt(t *testing.T) {
Source: &ethpb.Checkpoint{Root: []byte("C"), Epoch: 0}, Source: &ethpb.Checkpoint{Root: []byte("C"), Epoch: 0},
}, nil) }, 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") 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} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -256,7 +257,7 @@ func TestAttestToBlockHead_BlocksSurroundedAtt(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.Attestation{}), gomock.AssignableToTypeOf(&ethpb.Attestation{}),
).Return(&ethpb.AttestResponse{}, nil /* error */) ).Return(&ethpb.AttestResponse{}, nil /* error */)
validator.SubmitAttestation(context.Background(), 30, validatorPubKey) validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
m.validatorClient.EXPECT().GetAttestationData( m.validatorClient.EXPECT().GetAttestationData(
gomock.Any(), // ctx gomock.Any(), // ctx
@@ -267,7 +268,7 @@ func TestAttestToBlockHead_BlocksSurroundedAtt(t *testing.T) {
Source: &ethpb.Checkpoint{Root: []byte("C"), Epoch: 1}, Source: &ethpb.Checkpoint{Root: []byte("C"), Epoch: 1},
}, nil) }, 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") testutil.AssertLogsContain(t, hook, "Attempted to make a slashable attestation, rejected")
} }
@@ -293,7 +294,7 @@ func TestAttestToBlockHead_DoesNotAttestBeforeDelay(t *testing.T) {
).Return(&ethpb.AttestResponse{}, nil /* error */).Times(0) ).Return(&ethpb.AttestResponse{}, nil /* error */).Times(0)
timer := time.NewTimer(1 * time.Second) 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 <-timer.C
} }
@@ -310,7 +311,7 @@ func TestAttestToBlockHead_DoesAttestAfterDelay(t *testing.T) {
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -337,7 +338,7 @@ func TestAttestToBlockHead_DoesAttestAfterDelay(t *testing.T) {
gomock.Any(), gomock.Any(),
).Return(&ethpb.AttestResponse{}, nil).Times(1) ).Return(&ethpb.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) { 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} committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{ validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{
{ {
PublicKey: validatorKey.PublicKey.Marshal(), PublicKey: validatorPubKey.Marshal(),
CommitteeIndex: 5, CommitteeIndex: 5,
Committee: committee, Committee: committee,
ValidatorIndex: validatorIndex, ValidatorIndex: validatorIndex,
@@ -373,7 +374,7 @@ func TestAttestToBlockHead_CorrectBitfieldLength(t *testing.T) {
generatedAttestation = att generatedAttestation = att
}).Return(&ethpb.AttestResponse{}, nil /* error */) }).Return(&ethpb.AttestResponse{}, nil /* error */)
validator.SubmitAttestation(context.Background(), 30, validatorPubKey) validator.SubmitAttestation(context.Background(), 30, bytesutil.ToBytes48(validatorPubKey.Marshal()))
if len(generatedAttestation.AggregationBits) != 2 { if len(generatedAttestation.AggregationBits) != 2 {
t.Errorf("Wanted length %d, received %d", 2, len(generatedAttestation.AggregationBits)) t.Errorf("Wanted length %d, received %d", 2, len(generatedAttestation.AggregationBits))

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/go-bitfield"
slashpb "github.com/prysmaticlabs/prysm/proto/slashing" slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil"
@@ -22,7 +23,7 @@ type mocks struct {
} }
func setup(t *testing.T) (*validator, *mocks, func()) { 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) ctrl := gomock.NewController(t)
m := &mocks{ m := &mocks{
validatorClient: internal.NewMockBeaconNodeValidatorClient(ctrl), validatorClient: internal.NewMockBeaconNodeValidatorClient(ctrl),
@@ -42,7 +43,7 @@ func TestProposeBlock_DoesNotProposeGenesisBlock(t *testing.T) {
hook := logTest.NewGlobal() hook := logTest.NewGlobal()
validator, _, finish := setup(t) validator, _, finish := setup(t)
defer finish() 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") testutil.AssertLogsContain(t, hook, "Assigned to genesis slot, skipping proposal")
} }
@@ -57,7 +58,7 @@ func TestProposeBlock_DomainDataFailed(t *testing.T) {
gomock.Any(), // epoch gomock.Any(), // epoch
).Return(nil /*response*/, errors.New("uh oh")) ).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") testutil.AssertLogsContain(t, hook, "Failed to sign randao reveal")
} }
@@ -76,7 +77,7 @@ func TestProposeBlock_RequestBlockFailed(t *testing.T) {
gomock.Any(), // block request gomock.Any(), // block request
).Return(nil /*response*/, errors.New("uh oh")) ).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") testutil.AssertLogsContain(t, hook, "Failed to request block from beacon node")
} }
@@ -105,7 +106,7 @@ func TestProposeBlock_ProposeBlockFailed(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}), gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(nil /*response*/, errors.New("uh oh")) ).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") testutil.AssertLogsContain(t, hook, "Failed to propose block")
} }
@@ -139,10 +140,10 @@ func TestProposeBlock_BlocksDoubleProposal(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}), gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(&ethpb.ProposeResponse{}, nil /*error*/) ).Return(&ethpb.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") 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") testutil.AssertLogsContain(t, hook, "Tried to sign a double proposal")
} }
@@ -177,10 +178,10 @@ func TestProposeBlock_BlocksDoubleProposal_After54KEpochs(t *testing.T) {
).Return(&ethpb.ProposeResponse{}, nil /*error*/) ).Return(&ethpb.ProposeResponse{}, nil /*error*/)
farFuture := (params.BeaconConfig().WeakSubjectivityPeriod + 9) * params.BeaconConfig().SlotsPerEpoch 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") 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") testutil.AssertLogsContain(t, hook, "Tried to sign a double proposal")
} }
@@ -215,11 +216,11 @@ func TestProposeBlock_AllowsPastProposals(t *testing.T) {
).Times(2).Return(&ethpb.ProposeResponse{}, nil /*error*/) ).Times(2).Return(&ethpb.ProposeResponse{}, nil /*error*/)
farAhead := (params.BeaconConfig().WeakSubjectivityPeriod + 9) * params.BeaconConfig().SlotsPerEpoch 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") testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
past := (params.BeaconConfig().WeakSubjectivityPeriod - 400) * params.BeaconConfig().SlotsPerEpoch 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") testutil.AssertLogsDoNotContain(t, hook, "Tried to sign a double proposal")
} }
@@ -247,7 +248,7 @@ func TestProposeBlock_BroadcastsBlock(t *testing.T) {
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}), gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(&ethpb.ProposeResponse{}, nil /*error*/) ).Return(&ethpb.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) { func TestProposeBlock_BroadcastsBlock_WithGraffiti(t *testing.T) {
@@ -281,7 +282,7 @@ func TestProposeBlock_BroadcastsBlock_WithGraffiti(t *testing.T) {
return &ethpb.ProposeResponse{}, nil return &ethpb.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) { 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)) t.Errorf("Block was broadcast with the wrong graffiti field, wanted \"%v\", got \"%v\"", string(validator.graffiti), string(sentBlock.Block.Body.Graffiti))

View File

@@ -21,22 +21,17 @@ var (
Name: "tls-cert", Name: "tls-cert",
Usage: "Certificate for secure gRPC. Pass this and the tls-key flag in order to use gRPC securely.", 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. // UnencryptedKeysFlag specifies a file path of a JSON file of unencrypted validator keys; this should only
KeystorePathFlag = &cli.StringFlag{ // be used for test networks.
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 = &cli.StringFlag{ UnencryptedKeysFlag = &cli.StringFlag{
Name: "unencrypted-keys", 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: "", Value: "",
} }
// KeyManager specifies the key manager to use. // KeyManager specifies the key manager to use.
KeyManager = &cli.StringFlag{ KeyManager = &cli.StringFlag{
Name: "keymanager", Name: "keymanager",
Usage: "The keymanger to use (unencrypted, interop, keystore, wallet)", Usage: "For specifying the keymanager to use (remote, wallet, unencrypted, interop)",
Value: "", Value: "",
} }
// KeyManagerOpts specifies the key manager options. // 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", Usage: "The options for the keymanger, either a JSON string or path to same",
Value: "", 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 defines the ability to not log reward/penalty information during deployment
DisablePenaltyRewardLogFlag = &cli.BoolFlag{ DisablePenaltyRewardLogFlag = &cli.BoolFlag{
Name: "disable-rewards-penalties-logging", Name: "disable-rewards-penalties-logging",

View File

@@ -5,7 +5,6 @@ go_library(
srcs = [ srcs = [
"direct.go", "direct.go",
"direct_interop.go", "direct_interop.go",
"direct_keystore.go",
"direct_unencrypted.go", "direct_unencrypted.go",
"keymanager.go", "keymanager.go",
"log.go", "log.go",
@@ -19,7 +18,6 @@ go_library(
"//shared/bls:go_default_library", "//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library", "//shared/bytesutil:go_default_library",
"//shared/interop:go_default_library", "//shared/interop:go_default_library",
"//validator/accounts:go_default_library",
"@com_github_pkg_errors//:go_default_library", "@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library", "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//: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", "@com_github_wealdtech_go_eth2_wallet_types_v2//:go_default_library",
"@org_golang_google_grpc//:go_default_library", "@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//credentials:go_default_library", "@org_golang_google_grpc//credentials:go_default_library",
"@org_golang_x_crypto//ssh/terminal:go_default_library",
], ],
) )

View File

@@ -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 ""
}

View File

@@ -11,9 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/debug" "github.com/prysmaticlabs/prysm/shared/debug"
"github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/logutil" "github.com/prysmaticlabs/prysm/shared/logutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/version" "github.com/prysmaticlabs/prysm/shared/version"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/flags" "github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/node" "github.com/prysmaticlabs/prysm/validator/node"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@@ -39,8 +37,6 @@ var appFlags = []cli.Flag{
flags.BeaconRPCProviderFlag, flags.BeaconRPCProviderFlag,
flags.CertFlag, flags.CertFlag,
flags.GraffitiFlag, flags.GraffitiFlag,
flags.KeystorePathFlag,
flags.PasswordFlag,
flags.DisablePenaltyRewardLogFlag, flags.DisablePenaltyRewardLogFlag,
flags.UnencryptedKeysFlag, flags.UnencryptedKeysFlag,
flags.InteropStartIndex, flags.InteropStartIndex,
@@ -81,68 +77,6 @@ func main() {
starts proposer services, shardp2p connections, and more` starts proposer services, shardp2p connections, and more`
app.Version = version.GetVersion() app.Version = version.GetVersion()
app.Action = startNode 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.Flags = appFlags
app.Before = func(ctx *cli.Context) error { app.Before = func(ctx *cli.Context) error {

View File

@@ -7,7 +7,6 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//shared/testutil:go_default_library", "//shared/testutil:go_default_library",
"//validator/accounts:go_default_library",
"@in_gopkg_urfave_cli_v2//:go_default_library", "@in_gopkg_urfave_cli_v2//:go_default_library",
], ],
) )

View File

@@ -218,37 +218,25 @@ func selectKeyManager(ctx *cli.Context) (keymanager.KeyManager, error) {
manager = "interop" manager = "interop"
opts = fmt.Sprintf(`{"keys":%d,"offset":%d}`, numValidatorKeys, ctx.Uint64(flags.InteropStartIndex.Name)) 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)) 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 km keymanager.KeyManager
var help string var help string
var err error var err error
switch manager { switch manager {
case "remote":
km, help, err = keymanager.NewRemoteWallet(opts)
case "wallet":
km, help, err = keymanager.NewWallet(opts)
case "interop": case "interop":
km, help, err = keymanager.NewInterop(opts) km, help, err = keymanager.NewInterop(opts)
case "unencrypted": case "unencrypted":
km, help, err = keymanager.NewUnencrypted(opts) 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: default:
return nil, fmt.Errorf("unknown keymanager %q", manager) return nil, fmt.Errorf("unknown keymanager %q", manager)
} }

View File

@@ -3,10 +3,10 @@ package node
import ( import (
"flag" "flag"
"os" "os"
"path/filepath"
"testing" "testing"
"github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/validator/accounts"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
) )
@@ -14,18 +14,14 @@ import (
func TestNode_Builds(t *testing.T) { func TestNode_Builds(t *testing.T) {
app := cli.App{} app := cli.App{}
set := flag.NewFlagSet("test", 0) set := flag.NewFlagSet("test", 0)
set.String("datadir", testutil.TempDir()+"/datadir", "the node data directory") tmpDir := testutil.TempDir()
dir := testutil.TempDir() + "/keystore1" defer os.RemoveAll(tmpDir)
defer os.RemoveAll(dir) set.String("datadir", filepath.Join(tmpDir, "datadir"), "the node data directory")
defer os.RemoveAll(testutil.TempDir() + "/datadir") set.String("keymanager", "interop", "key manager")
set.String("keystore-path", dir, "path to keystore") set.String("keymanageropts", `{"keys":16,"offset":0}`, `key manager options`)
set.String("password", "1234", "validator account password")
set.String("verbosity", "debug", "log verbosity") set.String("verbosity", "debug", "log verbosity")
context := cli.NewContext(&app, set, nil) 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) _, err := NewValidatorClient(context)
if err != nil { if err != nil {
t.Fatalf("Failed to create ValidatorClient: %v", err) t.Fatalf("Failed to create ValidatorClient: %v", err)

View File

@@ -77,8 +77,6 @@ var appHelpFlagGroups = []flagGroup{
flags.CertFlag, flags.CertFlag,
flags.KeyManager, flags.KeyManager,
flags.KeyManagerOpts, flags.KeyManagerOpts,
flags.KeystorePathFlag,
flags.PasswordFlag,
flags.DisablePenaltyRewardLogFlag, flags.DisablePenaltyRewardLogFlag,
flags.UnencryptedKeysFlag, flags.UnencryptedKeysFlag,
flags.GraffitiFlag, flags.GraffitiFlag,