github.com/prysmaticlabs/prysm@v1.4.4/validator/accounts/accounts_delete.go (about) 1 package accounts 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/pkg/errors" 10 "github.com/prysmaticlabs/prysm/cmd/validator/flags" 11 "github.com/prysmaticlabs/prysm/shared/bytesutil" 12 "github.com/prysmaticlabs/prysm/shared/promptutil" 13 "github.com/prysmaticlabs/prysm/validator/accounts/iface" 14 "github.com/prysmaticlabs/prysm/validator/accounts/prompt" 15 "github.com/prysmaticlabs/prysm/validator/accounts/wallet" 16 "github.com/prysmaticlabs/prysm/validator/keymanager" 17 "github.com/prysmaticlabs/prysm/validator/keymanager/derived" 18 "github.com/prysmaticlabs/prysm/validator/keymanager/imported" 19 "github.com/urfave/cli/v2" 20 ) 21 22 // DeleteAccountCli deletes the accounts that the user requests to be deleted from the wallet. 23 // This function uses the CLI to extract necessary values. 24 func DeleteAccountCli(cliCtx *cli.Context) error { 25 w, err := wallet.OpenWalletOrElseCli(cliCtx, func(cliCtx *cli.Context) (*wallet.Wallet, error) { 26 return nil, wallet.ErrNoWalletFound 27 }) 28 if err != nil { 29 return errors.Wrap(err, "could not open wallet") 30 } 31 kManager, err := w.InitializeKeymanager(cliCtx.Context, iface.InitKeymanagerConfig{ListenForChanges: false}) 32 if err != nil { 33 return errors.Wrap(err, ErrCouldNotInitializeKeymanager) 34 } 35 validatingPublicKeys, err := kManager.FetchValidatingPublicKeys(cliCtx.Context) 36 if err != nil { 37 return err 38 } 39 if len(validatingPublicKeys) == 0 { 40 return errors.New("wallet is empty, no accounts to delete") 41 } 42 // Allow the user to interactively select the accounts to delete or optionally 43 // provide them via cli flags as a string of comma-separated, hex strings. 44 filteredPubKeys, err := filterPublicKeysFromUserInput( 45 cliCtx, 46 flags.DeletePublicKeysFlag, 47 validatingPublicKeys, 48 prompt.SelectAccountsDeletePromptText, 49 ) 50 if err != nil { 51 return errors.Wrap(err, "could not filter public keys for deletion") 52 } 53 rawPublicKeys := make([][]byte, len(filteredPubKeys)) 54 formattedPubKeys := make([]string, len(filteredPubKeys)) 55 for i, pk := range filteredPubKeys { 56 pubKeyBytes := pk.Marshal() 57 rawPublicKeys[i] = pubKeyBytes 58 formattedPubKeys[i] = fmt.Sprintf("%#x", bytesutil.Trunc(pubKeyBytes)) 59 } 60 allAccountStr := strings.Join(formattedPubKeys, ", ") 61 if !cliCtx.IsSet(flags.DeletePublicKeysFlag.Name) { 62 if len(filteredPubKeys) == 1 { 63 promptText := "Are you sure you want to delete 1 account? (%s) Y/N" 64 resp, err := promptutil.ValidatePrompt( 65 os.Stdin, fmt.Sprintf(promptText, au.BrightGreen(formattedPubKeys[0])), promptutil.ValidateYesOrNo, 66 ) 67 if err != nil { 68 return err 69 } 70 if strings.EqualFold(resp, "n") { 71 return nil 72 } 73 } else { 74 promptText := "Are you sure you want to delete %d accounts? (%s) Y/N" 75 if len(filteredPubKeys) == len(validatingPublicKeys) { 76 promptText = fmt.Sprintf("Are you sure you want to delete all accounts? Y/N (%s)", au.BrightGreen(allAccountStr)) 77 } else { 78 promptText = fmt.Sprintf(promptText, len(filteredPubKeys), au.BrightGreen(allAccountStr)) 79 } 80 resp, err := promptutil.ValidatePrompt(os.Stdin, promptText, promptutil.ValidateYesOrNo) 81 if err != nil { 82 return err 83 } 84 if strings.EqualFold(resp, "n") { 85 return nil 86 } 87 } 88 } 89 if err := DeleteAccount(cliCtx.Context, &Config{ 90 Wallet: w, 91 Keymanager: kManager, 92 DeletePublicKeys: rawPublicKeys, 93 }); err != nil { 94 return err 95 } 96 log.WithField("publicKeys", allAccountStr).Warn( 97 "Attempted to delete accounts. IMPORTANT: please run `validator accounts list` to ensure " + 98 "the public keys are indeed deleted. If they are still there, please file an issue at " + 99 "https://github.com/prysmaticlabs/prysm/issues/new") 100 return nil 101 } 102 103 // DeleteAccount deletes the accounts that the user requests to be deleted from the wallet. 104 func DeleteAccount(ctx context.Context, cfg *Config) error { 105 switch cfg.Wallet.KeymanagerKind() { 106 case keymanager.Remote: 107 return errors.New("cannot delete accounts for a remote keymanager") 108 case keymanager.Imported: 109 km, ok := cfg.Keymanager.(*imported.Keymanager) 110 if !ok { 111 return errors.New("not a imported keymanager") 112 } 113 if len(cfg.DeletePublicKeys) == 1 { 114 log.Info("Deleting account...") 115 } else { 116 log.Info("Deleting accounts...") 117 } 118 if err := km.DeleteAccounts(ctx, cfg.DeletePublicKeys); err != nil { 119 return errors.Wrap(err, "could not delete accounts") 120 } 121 case keymanager.Derived: 122 km, ok := cfg.Keymanager.(*derived.Keymanager) 123 if !ok { 124 return errors.New("not a derived keymanager") 125 } 126 if len(cfg.DeletePublicKeys) == 1 { 127 log.Info("Deleting account...") 128 } else { 129 log.Info("Deleting accounts...") 130 } 131 if err := km.DeleteAccounts(ctx, cfg.DeletePublicKeys); err != nil { 132 return errors.Wrap(err, "could not delete accounts") 133 } 134 default: 135 return fmt.Errorf(errKeymanagerNotSupported, cfg.Wallet.KeymanagerKind()) 136 } 137 return nil 138 }