mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Fix Mnemonic Validation (#10354)
* fix mnemonic validation * potuz's review * Add fuzz test for wallet recover Co-authored-by: prestonvanloon <preston@prysmaticlabs.com>
This commit is contained in:
@@ -70,8 +70,10 @@ go_test(
|
|||||||
"accounts_list_test.go",
|
"accounts_list_test.go",
|
||||||
"wallet_create_test.go",
|
"wallet_create_test.go",
|
||||||
"wallet_edit_test.go",
|
"wallet_edit_test.go",
|
||||||
|
"wallet_recover_fuzz_test.go",
|
||||||
"wallet_recover_test.go",
|
"wallet_recover_test.go",
|
||||||
],
|
],
|
||||||
|
data = glob(["testdata/**"]),
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//async/event:go_default_library",
|
"//async/event:go_default_library",
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
go test fuzz v1
|
||||||
|
string("0 ")
|
||||||
@@ -34,6 +34,11 @@ const (
|
|||||||
mnemonicPassphrasePromptText = "(Advanced) Enter the '25th word' passphrase for your mnemonic"
|
mnemonicPassphrasePromptText = "(Advanced) Enter the '25th word' passphrase for your mnemonic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrIncorrectWordNumber = errors.New("incorrect number of words provided")
|
||||||
|
ErrEmptyMnemonic = errors.New("phrase cannot be empty")
|
||||||
|
)
|
||||||
|
|
||||||
// RecoverWalletConfig to run the recover wallet function.
|
// RecoverWalletConfig to run the recover wallet function.
|
||||||
type RecoverWalletConfig struct {
|
type RecoverWalletConfig struct {
|
||||||
WalletDir string
|
WalletDir string
|
||||||
@@ -228,16 +233,18 @@ func inputNumAccounts(cliCtx *cli.Context) (int64, error) {
|
|||||||
// as specified(currently 24).
|
// as specified(currently 24).
|
||||||
func ValidateMnemonic(mnemonic string) error {
|
func ValidateMnemonic(mnemonic string) error {
|
||||||
if strings.Trim(mnemonic, " ") == "" {
|
if strings.Trim(mnemonic, " ") == "" {
|
||||||
return errors.New("phrase cannot be empty")
|
return ErrEmptyMnemonic
|
||||||
}
|
}
|
||||||
words := strings.Split(mnemonic, " ")
|
words := strings.Split(mnemonic, " ")
|
||||||
for i, word := range words {
|
validWordCount := 0
|
||||||
|
for _, word := range words {
|
||||||
if strings.Trim(word, " ") == "" {
|
if strings.Trim(word, " ") == "" {
|
||||||
words = append(words[:i], words[i+1:]...)
|
continue
|
||||||
}
|
}
|
||||||
|
validWordCount += 1
|
||||||
}
|
}
|
||||||
if len(words) != phraseWordCount {
|
if validWordCount != phraseWordCount {
|
||||||
return fmt.Errorf("phrase must be %d words, entered %d", phraseWordCount, len(words))
|
return errors.Wrapf(ErrIncorrectWordNumber, "phrase must be %d words, entered %d", phraseWordCount, validWordCount)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
19
validator/accounts/wallet_recover_fuzz_test.go
Normal file
19
validator/accounts/wallet_recover_fuzz_test.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//go:build go1.18
|
||||||
|
// +build go1.18
|
||||||
|
|
||||||
|
package accounts_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FuzzValidateMnemonic(f *testing.F) {
|
||||||
|
f.Add("bag wagon luxury iron swarm yellow course merge trumpet wide decide cash idea disagree deny teach canvas profit slice beach iron sting warfare slide")
|
||||||
|
f.Add("bag wagon luxury iron swarm yellow course merge trumpet wide cash idea disagree deny teach canvas profit iron sting warfare slide")
|
||||||
|
f.Add("bag wagon luxury iron swarm yellow course merge trumpet cash wide decide profit cash idea disagree deny teach canvas profit slice beach iron sting warfare slide")
|
||||||
|
f.Fuzz(func(t *testing.T, input string) {
|
||||||
|
accounts.ValidateMnemonic(input)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/cmd/validator/flags"
|
"github.com/prysmaticlabs/prysm/cmd/validator/flags"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
@@ -106,3 +107,56 @@ func TestRecoverDerivedWallet_AlreadyExists(t *testing.T) {
|
|||||||
// Trying to recover an HD wallet into a directory that already exists should give an error
|
// Trying to recover an HD wallet into a directory that already exists should give an error
|
||||||
require.ErrorContains(t, "a wallet already exists at this location", RecoverWalletCli(cliCtx))
|
require.ErrorContains(t, "a wallet already exists at this location", RecoverWalletCli(cliCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateMnemonic(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mnemonic string
|
||||||
|
wantErr bool
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Valid Mnemonic",
|
||||||
|
mnemonic: "bag wagon luxury iron swarm yellow course merge trumpet wide decide cash idea disagree deny teach canvas profit slice beach iron sting warfare slide",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid Mnemonic with too few words",
|
||||||
|
mnemonic: "bag wagon luxury iron swarm yellow course merge trumpet wide cash idea disagree deny teach canvas profit iron sting warfare slide",
|
||||||
|
wantErr: true,
|
||||||
|
err: ErrIncorrectWordNumber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid Mnemonic with too many words",
|
||||||
|
mnemonic: "bag wagon luxury iron swarm yellow course merge trumpet cash wide decide profit cash idea disagree deny teach canvas profit slice beach iron sting warfare slide",
|
||||||
|
wantErr: true,
|
||||||
|
err: ErrIncorrectWordNumber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Mnemonic",
|
||||||
|
mnemonic: "",
|
||||||
|
wantErr: true,
|
||||||
|
err: ErrEmptyMnemonic,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Junk Mnemonic",
|
||||||
|
mnemonic: " a ",
|
||||||
|
wantErr: true,
|
||||||
|
err: ErrIncorrectWordNumber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Junk Mnemonic ",
|
||||||
|
mnemonic: " evilpacket ",
|
||||||
|
wantErr: true,
|
||||||
|
err: ErrIncorrectWordNumber,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
err := ValidateMnemonic(tt.mnemonic)
|
||||||
|
if (err != nil) != tt.wantErr || (tt.wantErr && !errors.Is(err, tt.err)) {
|
||||||
|
t.Errorf("ValidateMnemonic() error = %v, wantErr %v", err, tt.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user