mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-17 23:38:46 +00:00
9d979de4ed
* implementation using petname and keystore * writing new account to disk along with password * more logic for properly writing accounts * print out mnemonic * save deposit data rlp * write deposit tx and ssz deposit data to account path * wrap up account creation * fix prompt * generate deposit tx * direct account creation test * fix up formatting * lint * match formatting * more sustainable approach towards unmarshaling config file * resolve feedback * fix broken import * comprehensive tests for create account * tests pass * Merge branch 'master' into direct-keys * tidy * Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys * Merge refs/heads/master into direct-keys * gaz * Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys * nondeterministic names * comment * gaz * better error wrap * Merge refs/heads/master into direct-keys * docker deps * Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * Merge refs/heads/master into direct-keys * ivan feedback * Merge refs/heads/master into direct-keys * Update validator/accounts/v2/wallet.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * fixed tests and comments * Merge refs/heads/master into direct-keys
146 lines
4.4 KiB
Go
146 lines
4.4 KiB
Go
package direct
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
|
"github.com/prysmaticlabs/go-ssz"
|
|
"github.com/prysmaticlabs/prysm/shared/bls"
|
|
"github.com/prysmaticlabs/prysm/shared/depositutil"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
|
"github.com/tyler-smith/go-bip39"
|
|
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
|
|
)
|
|
|
|
type mockWallet struct {
|
|
files map[string][]byte
|
|
}
|
|
|
|
func (m *mockWallet) AccountsDir() string {
|
|
return ""
|
|
}
|
|
|
|
func (m *mockWallet) WriteAccountToDisk(ctx context.Context, password string) (string, error) {
|
|
return "mockaccount", nil
|
|
}
|
|
|
|
func (m *mockWallet) WriteFileForAccount(
|
|
ctx context.Context,
|
|
accountName string,
|
|
fileName string,
|
|
data []byte,
|
|
) error {
|
|
m.files[fileName] = data
|
|
return nil
|
|
}
|
|
|
|
type mockMnemonicGenerator struct {
|
|
generatedMnemonics []string
|
|
}
|
|
|
|
func (m *mockMnemonicGenerator) Generate(data []byte) (string, error) {
|
|
newMnemonic, err := bip39.NewMnemonic(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
m.generatedMnemonics = append(m.generatedMnemonics, newMnemonic)
|
|
return newMnemonic, nil
|
|
}
|
|
|
|
func (m *mockMnemonicGenerator) ConfirmAcknowledgement(phrase string) error {
|
|
return nil
|
|
}
|
|
|
|
func TestKeymanager_CreateAccount(t *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
wallet := &mockWallet{files: make(map[string][]byte)}
|
|
mnemonicGenerator := &mockMnemonicGenerator{
|
|
generatedMnemonics: make([]string, 0),
|
|
}
|
|
dr := &Keymanager{
|
|
wallet: wallet,
|
|
mnemonicGenerator: mnemonicGenerator,
|
|
}
|
|
ctx := context.Background()
|
|
password := "secretPassw0rd$1999"
|
|
if err := dr.CreateAccount(ctx, password); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Ensure the keystore file was written to the wallet
|
|
// and ensure we can decrypt it using the EIP-2335 standard.
|
|
encodedKeystore, ok := wallet.files[keystoreFileName]
|
|
if !ok {
|
|
t.Fatalf("Expected to have stored %s in wallet", keystoreFileName)
|
|
}
|
|
keystoreJSON := make(map[string]interface{})
|
|
if err := json.Unmarshal(encodedKeystore, &keystoreJSON); err != nil {
|
|
t.Fatalf("Could not decode keystore json: %v", err)
|
|
}
|
|
|
|
// We extract the validator signing private key from the keystore
|
|
// by utilizing the password and initialize a new BLS secret key from
|
|
// its raw bytes.
|
|
decryptor := keystorev4.New()
|
|
rawSigningKey, err := decryptor.Decrypt(keystoreJSON, []byte(password))
|
|
if err != nil {
|
|
t.Fatalf("Could not decrypt validator signing key: %v", err)
|
|
}
|
|
validatorSigningKey, err := bls.SecretKeyFromBytes(rawSigningKey)
|
|
if err != nil {
|
|
t.Fatalf("Could not instantiate bls secret key from bytes: %v", err)
|
|
}
|
|
|
|
// Decode the deposit_data.ssz file and confirm
|
|
// the public key matches the public key from the
|
|
// account's decrypted keystore.
|
|
encodedDepositData, ok := wallet.files[depositDataFileName]
|
|
if !ok {
|
|
t.Fatalf("Expected to have stored %s in wallet", depositDataFileName)
|
|
}
|
|
depositData := ðpb.Deposit_Data{}
|
|
if err := ssz.Unmarshal(encodedDepositData, depositData); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
depositPublicKey := depositData.PublicKey
|
|
publicKey := validatorSigningKey.PublicKey().Marshal()
|
|
if !bytes.Equal(depositPublicKey, publicKey) {
|
|
t.Errorf(
|
|
"Expected deposit data public key %#x to match public key from keystore %#x",
|
|
depositPublicKey,
|
|
publicKey,
|
|
)
|
|
}
|
|
|
|
// We ensure the mnemonic phrase has successfully been generated.
|
|
if len(mnemonicGenerator.generatedMnemonics) != 1 {
|
|
t.Fatal("Expected to have generated new mnemonic for private key")
|
|
}
|
|
mnemonicPhrase := mnemonicGenerator.generatedMnemonics[0]
|
|
rawWithdrawalBytes, err := bip39.EntropyFromMnemonic(mnemonicPhrase)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
validatorWithdrawalKey, err := bls.SecretKeyFromBytes(rawWithdrawalBytes)
|
|
if err != nil {
|
|
t.Fatalf("Could not instantiate bls secret key from bytes: %v", err)
|
|
}
|
|
|
|
// We then verify the withdrawal hash created from the recovered withdrawal key
|
|
// given the mnemonic phrase does indeed verify with the deposit data that was persisted on disk.
|
|
withdrawalHash := depositutil.WithdrawalCredentialsHash(validatorWithdrawalKey)
|
|
if !bytes.Equal(withdrawalHash, depositData.WithdrawalCredentials) {
|
|
t.Errorf(
|
|
"Expected matching withdrawal credentials, got %#x, received %#x",
|
|
withdrawalHash,
|
|
depositData.WithdrawalCredentials,
|
|
)
|
|
}
|
|
testutil.AssertLogsContain(t, hook, "Successfully created new validator account")
|
|
}
|