-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Revert "Updates for remote keymanager (#5260)" This reverts commit bbcd895. * Revert "Remove keystore keymanager from validator (#5236)" This reverts commit 4600877. * Revert "Update eth2 wallet keymanager (#4984)" This reverts commit 7f7ef43. Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
- Loading branch information
1 parent
0a64620
commit 0ea2bbb
Showing
22 changed files
with
557 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
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", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.