mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Return error when using unsupported mnemonic language (#11805)
* Return error when using unsupported mnemonic language * Fix failing tests * More test fixes * Add MnemonicLanguage to CreateWalletRequest * Add MnemonicLanguage to remaining tests * Add language to error * Add missing (.) * Set default language + fix renumbered fields * Replace hardcoded language with default var * default set * gaz * fix proto field setting * fix up * Remove WithMnemonicLanguage from tests * Remove WithMnemonicLanguage from tests * Fix conflicting information failure * Gazelle + remove hardcoded english values * fix * Fix tests Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -36,7 +36,7 @@ func TestDerivedKeymanager_MnemnonicPassphrase_DifferentResults(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
numAccounts := 5
|
||||
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", "mnemonicpass", numAccounts)
|
||||
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, DefaultMnemonicLanguage, "mnemonicpass", numAccounts)
|
||||
require.NoError(t, err)
|
||||
without25thWord, err := km.FetchValidatingPublicKeys(ctx)
|
||||
require.NoError(t, err)
|
||||
@@ -51,7 +51,7 @@ func TestDerivedKeymanager_MnemnonicPassphrase_DifferentResults(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
// No mnemonic passphrase this time.
|
||||
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", "", numAccounts)
|
||||
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, DefaultMnemonicLanguage, "", numAccounts)
|
||||
require.NoError(t, err)
|
||||
with25thWord, err := km.FetchValidatingPublicKeys(ctx)
|
||||
require.NoError(t, err)
|
||||
@@ -70,14 +70,14 @@ func TestDerivedKeymanager_RecoverSeedRoundTrip(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
wanted := bip39.NewSeed(mnemonic, "")
|
||||
|
||||
got, err := seedFromMnemonic(mnemonic, "", "" /* no passphrase */)
|
||||
got, err := seedFromMnemonic(mnemonic, DefaultMnemonicLanguage, "" /* no passphrase */)
|
||||
require.NoError(t, err)
|
||||
// Ensure the derived seed matches.
|
||||
assert.DeepEqual(t, wanted, got)
|
||||
}
|
||||
|
||||
func TestDerivedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
|
||||
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, "", "")
|
||||
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, DefaultMnemonicLanguage, "")
|
||||
require.NoError(t, err)
|
||||
wallet := &mock.Wallet{
|
||||
Files: make(map[string]map[string][]byte),
|
||||
@@ -91,7 +91,7 @@ func TestDerivedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
numAccounts := 5
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", "", numAccounts)
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, DefaultMnemonicLanguage, "", numAccounts)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Fetch the public keys.
|
||||
@@ -116,7 +116,7 @@ func TestDerivedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDerivedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
|
||||
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, "", "")
|
||||
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, DefaultMnemonicLanguage, "")
|
||||
require.NoError(t, err)
|
||||
wallet := &mock.Wallet{
|
||||
Files: make(map[string]map[string][]byte),
|
||||
@@ -130,7 +130,7 @@ func TestDerivedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
numAccounts := 5
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", "", numAccounts)
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, DefaultMnemonicLanguage, "", numAccounts)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Fetch the private keys.
|
||||
@@ -167,7 +167,7 @@ func TestDerivedKeymanager_Sign(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
numAccounts := 5
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", "", numAccounts)
|
||||
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, DefaultMnemonicLanguage, "", numAccounts)
|
||||
require.NoError(t, err)
|
||||
|
||||
pubKeys, err := dr.FetchValidatingPublicKeys(ctx)
|
||||
|
||||
@@ -20,13 +20,22 @@ type MnemonicGenerator struct {
|
||||
skipMnemonicConfirm bool
|
||||
}
|
||||
|
||||
// ErrUnsupportedMnemonicLanguage is returned when trying to use an unsupported mnemonic langauge.
|
||||
var (
|
||||
DefaultMnemonicLanguage = "english"
|
||||
ErrUnsupportedMnemonicLanguage = errors.New("unsupported mnemonic language")
|
||||
)
|
||||
|
||||
// GenerateAndConfirmMnemonic requires confirming the generated mnemonics.
|
||||
func GenerateAndConfirmMnemonic(mnemonicLanguage string, skipMnemonicConfirm bool) (string, error) {
|
||||
mnemonicRandomness := make([]byte, 32)
|
||||
if _, err := rand.NewGenerator().Read(mnemonicRandomness); err != nil {
|
||||
return "", errors.Wrap(err, "could not initialize mnemonic source of randomness")
|
||||
}
|
||||
setBip39Lang(mnemonicLanguage)
|
||||
err := setBip39Lang(mnemonicLanguage)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
m := &MnemonicGenerator{
|
||||
skipMnemonicConfirm: skipMnemonicConfirm,
|
||||
}
|
||||
@@ -75,15 +84,18 @@ func (m *MnemonicGenerator) ConfirmAcknowledgement(phrase string) error {
|
||||
// Uses the provided mnemonic seed phrase to generate the
|
||||
// appropriate seed file for recovering a derived wallets.
|
||||
func seedFromMnemonic(mnemonic, mnemonicLanguage, mnemonicPassphrase string) ([]byte, error) {
|
||||
setBip39Lang(mnemonicLanguage)
|
||||
err := setBip39Lang(mnemonicLanguage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok := bip39.IsMnemonicValid(mnemonic); !ok {
|
||||
return nil, bip39.ErrInvalidMnemonic
|
||||
}
|
||||
return bip39.NewSeed(mnemonic, mnemonicPassphrase), nil
|
||||
}
|
||||
|
||||
func setBip39Lang(lang string) {
|
||||
wordlist := wordlists.English
|
||||
func setBip39Lang(lang string) error {
|
||||
var wordlist []string
|
||||
allowedLanguages := map[string][]string{
|
||||
"chinese_simplified": wordlists.ChineseSimplified,
|
||||
"chinese_traditional": wordlists.ChineseTraditional,
|
||||
@@ -98,6 +110,9 @@ func setBip39Lang(lang string) {
|
||||
|
||||
if wl, ok := allowedLanguages[lang]; ok {
|
||||
wordlist = wl
|
||||
} else {
|
||||
return errors.Wrapf(ErrUnsupportedMnemonicLanguage, "%s", lang)
|
||||
}
|
||||
bip39.SetWordList(wordlist)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package derived
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
"github.com/tyler-smith/go-bip39"
|
||||
@@ -24,23 +25,29 @@ func Test_setBip39Lang(t *testing.T) {
|
||||
tests := []struct {
|
||||
lang string
|
||||
expectedWordlist []string
|
||||
wantErr error
|
||||
}{
|
||||
{lang: "english", expectedWordlist: wordlists.English},
|
||||
{lang: "chinese_traditional", expectedWordlist: wordlists.ChineseTraditional},
|
||||
{lang: "chinese_simplified", expectedWordlist: wordlists.ChineseSimplified},
|
||||
{lang: "czech", expectedWordlist: wordlists.Czech},
|
||||
{lang: "french", expectedWordlist: wordlists.French},
|
||||
{lang: "japanese", expectedWordlist: wordlists.Japanese},
|
||||
{lang: "korean", expectedWordlist: wordlists.Korean},
|
||||
{lang: "italian", expectedWordlist: wordlists.Italian},
|
||||
{lang: "spanish", expectedWordlist: wordlists.Spanish},
|
||||
{lang: "undefined", expectedWordlist: wordlists.English},
|
||||
{lang: "english", expectedWordlist: wordlists.English, wantErr: nil},
|
||||
{lang: "chinese_traditional", expectedWordlist: wordlists.ChineseTraditional, wantErr: nil},
|
||||
{lang: "chinese_simplified", expectedWordlist: wordlists.ChineseSimplified, wantErr: nil},
|
||||
{lang: "czech", expectedWordlist: wordlists.Czech, wantErr: nil},
|
||||
{lang: "french", expectedWordlist: wordlists.French, wantErr: nil},
|
||||
{lang: "japanese", expectedWordlist: wordlists.Japanese, wantErr: nil},
|
||||
{lang: "korean", expectedWordlist: wordlists.Korean, wantErr: nil},
|
||||
{lang: "italian", expectedWordlist: wordlists.Italian, wantErr: nil},
|
||||
{lang: "spanish", expectedWordlist: wordlists.Spanish, wantErr: nil},
|
||||
{lang: "undefined", expectedWordlist: []string{}, wantErr: errors.Wrapf(ErrUnsupportedMnemonicLanguage, "%s", "undefined")},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.lang, func(t *testing.T) {
|
||||
setBip39Lang(tt.lang)
|
||||
wordlist := bip39.GetWordList()
|
||||
assert.DeepEqual(t, tt.expectedWordlist, wordlist, "Expected wordlist to match")
|
||||
err := setBip39Lang(tt.lang)
|
||||
if err != nil {
|
||||
assert.Equal(t, tt.wantErr.Error(), err.Error())
|
||||
} else {
|
||||
assert.Equal(t, tt.wantErr, err)
|
||||
wordlist := bip39.GetWordList()
|
||||
assert.DeepEqual(t, tt.expectedWordlist, wordlist, "Expected wordlist to match")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user