CLEANUP: validator exit prompt (#13057)

* removing check special phrase in url from validator exit

* fixing missed tests

* fixing unit test and addressing preston/sammy's comments

* fixing test

* sammy's comments

* deepsource recommendation

* Update validator/accounts/accounts_helper.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* sammy's review

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
james-prysm
2023-10-18 09:00:25 -05:00
committed by GitHub
parent 4809da62cc
commit 71fa70ce40
6 changed files with 19 additions and 28 deletions

View File

@@ -90,7 +90,7 @@ func TestExitAccountsCli_OK(t *testing.T) {
// Prepare user input for final confirmation step // Prepare user input for final confirmation step
var stdin bytes.Buffer var stdin bytes.Buffer
stdin.Write([]byte(accounts.ExitPassphrase)) stdin.Write([]byte("Y"))
rawPubKeys, formattedPubKeys, err := accounts.FilterExitAccountsFromUserInput( rawPubKeys, formattedPubKeys, err := accounts.FilterExitAccountsFromUserInput(
cliCtx, &stdin, validatingPublicKeys, false, cliCtx, &stdin, validatingPublicKeys, false,
) )
@@ -190,7 +190,7 @@ func TestExitAccountsCli_OK_AllPublicKeys(t *testing.T) {
// Prepare user input for final confirmation step // Prepare user input for final confirmation step
var stdin bytes.Buffer var stdin bytes.Buffer
stdin.Write([]byte(accounts.ExitPassphrase)) stdin.Write([]byte("Y"))
rawPubKeys, formattedPubKeys, err := accounts.FilterExitAccountsFromUserInput( rawPubKeys, formattedPubKeys, err := accounts.FilterExitAccountsFromUserInput(
cliCtx, &stdin, validatingPublicKeys, false, cliCtx, &stdin, validatingPublicKeys, false,
) )

View File

@@ -79,10 +79,12 @@ func ValidatePasswordInput(input string) error {
return nil return nil
} }
// ValidatePhrase checks whether the user input is equal to the wanted phrase. The verification is case sensitive. // ValidatePhrase checks whether the user input is equal to the wanted phrase(s).
func ValidatePhrase(input, wantedPhrase string) error { func ValidatePhrase(input string, wantedPhrases ...string) error {
if strings.TrimSpace(input) != wantedPhrase { for _, wantedPhrase := range wantedPhrases {
return errIncorrectPhrase if strings.EqualFold(strings.TrimSpace(input), wantedPhrase) {
return nil
}
} }
return nil return errIncorrectPhrase
} }

View File

@@ -153,9 +153,7 @@ func TestValidatePhrase(t *testing.T) {
assert.NotNil(t, err) assert.NotNil(t, err)
assert.ErrorContains(t, errIncorrectPhrase.Error(), err) assert.ErrorContains(t, errIncorrectPhrase.Error(), err)
}) })
t.Run("wrong letter case", func(t *testing.T) { t.Run("any letter case", func(t *testing.T) {
err := ValidatePhrase("Wanted Phrase", wantedPhrase) assert.NoError(t, ValidatePhrase("Wanted Phrase", wantedPhrase))
assert.NotNil(t, err)
assert.ErrorContains(t, errIncorrectPhrase.Error(), err)
}) })
} }

View File

@@ -33,9 +33,6 @@ type PerformExitCfg struct {
OutputDirectory string OutputDirectory string
} }
// ExitPassphrase exported for use in test.
const ExitPassphrase = "Exit my validator"
// Exit performs a voluntary exit on one or more accounts. // Exit performs a voluntary exit on one or more accounts.
func (acm *AccountsCLIManager) Exit(ctx context.Context) error { func (acm *AccountsCLIManager) Exit(ctx context.Context) error {
// User decided to cancel the voluntary exit. // User decided to cancel the voluntary exit.
@@ -106,7 +103,7 @@ func PerformVoluntaryExit(
} else { } else {
log.WithError(err).Errorf("voluntary exit failed for account %s", cfg.FormattedPubKeys[i]) log.WithError(err).Errorf("voluntary exit failed for account %s", cfg.FormattedPubKeys[i])
} }
} else if err := writeSignedVoluntaryExitJSON(ctx, sve, cfg.OutputDirectory); err != nil { } else if err := writeSignedVoluntaryExitJSON(sve, cfg.OutputDirectory); err != nil {
log.WithError(err).Error("failed to write voluntary exit") log.WithError(err).Error("failed to write voluntary exit")
} }
} else if err := client.ProposeExit(ctx, cfg.ValidatorClient, cfg.Keymanager.Sign, key, epoch); err != nil { } else if err := client.ProposeExit(ctx, cfg.ValidatorClient, cfg.Keymanager.Sign, key, epoch); err != nil {
@@ -180,7 +177,7 @@ func displayExitInfo(rawExitedKeys [][]byte, trimmedExitedKeys []string) {
} }
} }
func writeSignedVoluntaryExitJSON(ctx context.Context, sve *eth.SignedVoluntaryExit, outputDirectory string) error { func writeSignedVoluntaryExitJSON(sve *eth.SignedVoluntaryExit, outputDirectory string) error {
if err := file.MkdirAll(outputDirectory); err != nil { if err := file.MkdirAll(outputDirectory); err != nil {
return err return err
} }

View File

@@ -1,7 +1,6 @@
package accounts package accounts
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"path" "path"
@@ -53,7 +52,7 @@ func TestWriteSignedVoluntaryExitJSON(t *testing.T) {
} }
output := path.Join(bazel.TestTmpDir(), "TestWriteSignedVoluntaryExitJSON") output := path.Join(bazel.TestTmpDir(), "TestWriteSignedVoluntaryExitJSON")
require.NoError(t, writeSignedVoluntaryExitJSON(context.Background(), sve, output)) require.NoError(t, writeSignedVoluntaryExitJSON(sve, output))
b, err := file.ReadFileAsBytes(path.Join(output, "validator-exit-300.json")) b, err := file.ReadFileAsBytes(path.Join(output, "validator-exit-300.json"))
require.NoError(t, err) require.NoError(t, err)

View File

@@ -202,21 +202,16 @@ func FilterExitAccountsFromUserInput(
return rawPubKeys, formattedPubKeys, nil return rawPubKeys, formattedPubKeys, nil
} }
promptHeader := au.Red("===============IMPORTANT===============") promptHeader := au.Red("===============CONFIRMATION NEEDED===============")
promptDescription := "Please navigate to the following website and make sure you understand the current implications " + promptQuestion := "continue with the voluntary exit? (y/n)"
"of a voluntary exit before making the final decision:" promptText := fmt.Sprintf("%s\n%s", promptHeader, promptQuestion)
promptURL := au.Blue("https://docs.prylabs.network/docs/wallet/exiting-a-validator") resp, err := prompt.ValidatePrompt(r, promptText, prompt.ValidateYesOrNo)
promptQuestion := "If you still want to continue with the voluntary exit, please input a phrase found at the above URL"
promptText := fmt.Sprintf("%s\n%s\n%s\n%s", promptHeader, promptDescription, promptURL, promptQuestion)
resp, err := prompt.ValidatePrompt(r, promptText, func(input string) error {
return prompt.ValidatePhrase(input, ExitPassphrase)
})
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if strings.EqualFold(resp, "n") { if strings.EqualFold(resp, "n") {
log.Info("Voluntary exit aborted")
return nil, nil, nil return nil, nil, nil
} }
return rawPubKeys, formattedPubKeys, nil return rawPubKeys, formattedPubKeys, nil
} }