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  }