prysm-pulse/validator/accounts/prompt/prompt.go
Raul Jordan 92932ae58e
[Feature] - Slashing Interchange Support (#8024)
* Change LowestSignedProposal to Also Return a Boolean for Slashing Protection (#8020)

* amend to use bools

* ineff assign

* comment

* Update `LowestSignedTargetEpoch` to include exists (#8004)

* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

* Add eip checks to ensure epochs cant be lower than db ones

* Should be less than equal to

* Check if epoch exists in DB getters

* Revert run time checks

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* Export Attesting History for Slashing Interchange Standard (#8027)

* added in att history checks

* logic for export

* export return nil

* test for export atts

* round trip passes first try!

* rem println

* fix up tests

* pass test

* Validate Proposers Are Not Slashable With Regard to Data Within Slasher Interchange JSON (#8031)

* filter slashable blocks and atts in same json stub

* add filter blocks func

* add test for filtering out the bad public keys

* Export Slashing Protection History Via CLI (#8040)

* include cli entrypoint for history exports

* builds properly

* test to confirm we export the data as expected

* abstract helpers properly

* full test suite

* gaz

* better errors

* marshal ident

* Add the additional eip-3076 attestation checks (#7966)

* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

* Add eip checks to ensure epochs cant be lower than db ones

* Should be less than equal to

* Check if epoch exists in DB getters

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Add EIP-3076 Invariants for Proposer Slashing Protection (#8067)

* add invariant for proposer protection

* write different test cases

* pass tests

* Add EIP-3076 Interchange JSON CLI command to validator (#7880)

* Import JSON CLI

* CLI impotr

* f

* Begin adding new commands in slashing protection

* Move testing helpers to separate packae

* Add command for importing slashing protection JSONs

* fix import cycle

* fix test

* Undo cleaning changes

* Improvements

* Add better prompts

* Fix prompt

* Fix

* Fix

* Fix

* Fix conflict

* Fix

* Fixes

* Fixes

* Fix exported func

* test func

* Fixes

* fix test

* simplify import and standardize with export

* add round trip test

* true integration test works

* fix up comments

* logrus

* better error

* fix build

* build fix

* Update validator/slashing-protection/cli_export.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* Update validator/slashing-protection/cli_import.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* Filter Slashable Attester Public Keys in Slashing Interchange Import (#8051)

* filter slashable attesters from the same JSON

* builds

* fix up initially broken test

* circular dep

* import fix

* giz

* added in attesting history package

* add test for filter slashable attester keys

* pass tests

* Save Slashable Keys to Disk in the Validator Client (#8082)

* begin db funcs

* add in test and bucket

* gaz

* rem changes to import

* ineff assign

* add godoc

* Properly Handle Duplicate Public Key Entries in Slashing Interchange Imports (#8089)

* Prevent Blacklisted Public Keys from Slashing Protection Imports from Having Duties at Runtime (#8084)

* tests on update duties

* ensure the slashable public keys are filtered out from update duties via test

* begin test

* attempt test

* rename for better context

* pass tests

* deep source

* ensure tests pass

* Check for Signing Root Mismatch When Submitting Proposals and Importing Proposals in Slashing Interchange (#8085)

* flexible signing root

* add test

* add tests

* fix test

* Preston's comments

* res tests

* ensure we consider the case for minimum proposals

* pass test

* tests passing

* rem unused code

* Set Empty Epochs in Between Attestations as FAR_FUTURE_EPOCH in Attesting History (#8113)

* set target data

* all tests passing

* ineff assign

* signing root

* Add Slashing Interchange, EIP-3076, Spec Tests to Prysm (#7858)

* Add interchange test framework

* add checks for attestations

* Import genesis root if necessary

* flexible signing root

* add test

* Sync

* fix up test build

* only 3 failing tests now

* two failing

* attempting to debug problems in conformity tests

* include latest changes

* protect test in validator/client passing

* pass tests

* imports

* spec tests passing with bazel

* gh archive link to spectests using tar.gz suffix

* rev

* rev more comment changes

* fix sha

* godoc

* add back save

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Implement Migration for Unattested Epochs in Attesting History Database (#8121)

* migrate attesting history backbone done

* begin migration logic

* implement migration logic

* migration test

* add test

* migration logic

* bazel

* migration to its own file

* Handle empty blocks and attestations in interchange json and sort interchange json by public key (#8132)

* Handle empty blocks and attestations in interchange json

* add test

* sort json

* easier empty arrays

* pass test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* builds

* more tests finally build

* Align Slashing Interchange With Optimized Slashing Protection (#8268)

* attestation history should account for multiple targets per source

* attempt at some fixes

* attempt some test fixes

* experimenting with sorting

* only one more failing test

* tests now pass

* slash protect tests passing

* only few tests now failing

* only spec tests failing now

* spec tests passing

* all tests passing

* helper function for verifying double votes

* use helper

* gaz

* deep source

* tests fixed

* expect specific number of times for domain data calls

* final comments

* Batch Save Imported EIP-3076 Attestations (#8304)

* optimize save

* test added

* add test for sad path

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* revert bad find replace

* add comment to db func

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Shay Zluf <thezluf@gmail.com>
2021-01-22 17:12:22 -06:00

174 lines
5.3 KiB
Go

package prompt
import (
"fmt"
"os"
"strings"
"github.com/logrusorgru/aurora"
"github.com/manifoldco/promptui"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager/remote"
"github.com/urfave/cli/v2"
)
const (
// ImportKeysDirPromptText for the import keys cli function.
ImportKeysDirPromptText = "Enter the directory or filepath where your keystores to import are located"
// DataDirDirPromptText for the validator database directory.
DataDirDirPromptText = "Enter the directory of the validator database you would like to use"
// SlashingProtectionJSONPromptText for the EIP-3076 slashing protection JSON prompt.
SlashingProtectionJSONPromptText = "Enter the the filepath of your EIP-3076 Slashing Protection JSON from your previously used validator client"
// WalletDirPromptText for the wallet.
WalletDirPromptText = "Enter a wallet directory"
// SelectAccountsDeletePromptText --
SelectAccountsDeletePromptText = "Select the account(s) you would like to delete"
// SelectAccountsBackupPromptText --
SelectAccountsBackupPromptText = "Select the account(s) you wish to backup"
// SelectAccountsVoluntaryExitPromptText --
SelectAccountsVoluntaryExitPromptText = "Select the account(s) on which you wish to perform a voluntary exit"
// SelectAccountsDisablePromptText --
SelectAccountsDisablePromptText = "Select the account(s) you would like to disable"
// SelectAccountsEnablePromptText --
SelectAccountsEnablePromptText = "Select the account(s) you would like to enable"
)
var au = aurora.NewAurora(true)
// InputDirectory from the cli.
func InputDirectory(cliCtx *cli.Context, promptText string, flag *cli.StringFlag) (string, error) {
directory := cliCtx.String(flag.Name)
if cliCtx.IsSet(flag.Name) {
return fileutil.ExpandPath(directory)
}
// Append and log the appropriate directory name depending on the flag used.
if flag.Name == flags.WalletDirFlag.Name {
ok, err := fileutil.HasDir(directory)
if err != nil {
return "", errors.Wrapf(err, "could not check if wallet dir %s exists", directory)
}
if ok {
log.Infof("%s %s", au.BrightMagenta("(wallet path)"), directory)
return directory, nil
}
}
inputtedDir, err := promptutil.DefaultPrompt(au.Bold(promptText).String(), directory)
if err != nil {
return "", err
}
if inputtedDir == directory {
return directory, nil
}
return fileutil.ExpandPath(inputtedDir)
}
// InputRemoteKeymanagerConfig via the cli.
func InputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.KeymanagerOpts, error) {
addr := cliCtx.String(flags.GrpcRemoteAddressFlag.Name)
requireTls := !cliCtx.Bool(flags.DisableRemoteSignerTlsFlag.Name)
crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name)
key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name)
ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name)
log.Info("Input desired configuration")
var err error
if addr == "" {
addr, err = promptutil.ValidatePrompt(
os.Stdin,
"Remote gRPC address (such as host.example.com:4000)",
promptutil.NotEmpty)
if err != nil {
return nil, err
}
}
if requireTls && crt == "" {
crt, err = promptutil.ValidatePrompt(
os.Stdin,
"Path to TLS crt (such as /path/to/client.crt)",
validateCertPath)
if err != nil {
return nil, err
}
}
if requireTls && key == "" {
key, err = promptutil.ValidatePrompt(
os.Stdin,
"Path to TLS key (such as /path/to/client.key)",
validateCertPath)
if err != nil {
return nil, err
}
}
if requireTls && ca == "" {
ca, err = promptutil.ValidatePrompt(
os.Stdin,
"Path to certificate authority (CA) crt (such as /path/to/ca.crt)",
validateCertPath)
if err != nil {
return nil, err
}
}
crtPath, keyPath, caPath := "", "", ""
if crt != "" {
crtPath, err = fileutil.ExpandPath(strings.TrimRight(crt, "\r\n"))
if err != nil {
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
}
}
if key != "" {
keyPath, err = fileutil.ExpandPath(strings.TrimRight(key, "\r\n"))
if err != nil {
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
}
}
if ca != "" {
caPath, err = fileutil.ExpandPath(strings.TrimRight(ca, "\r\n"))
if err != nil {
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
}
}
newCfg := &remote.KeymanagerOpts{
RemoteCertificate: &remote.CertificateConfig{
RequireTls: requireTls,
ClientCertPath: crtPath,
ClientKeyPath: keyPath,
CACertPath: caPath,
},
RemoteAddr: addr,
}
fmt.Printf("%s\n", newCfg)
return newCfg, nil
}
func validateCertPath(input string) error {
if input == "" {
return errors.New("crt path cannot be empty")
}
if !promptutil.IsValidUnicode(input) {
return errors.New("not valid unicode")
}
if !fileutil.FileExists(input) {
return fmt.Errorf("no crt found at path: %s", input)
}
return nil
}
// FormatPromptError for the user.
func FormatPromptError(err error) error {
switch err {
case promptui.ErrAbort:
return errors.New("wallet creation aborted, closing")
case promptui.ErrInterrupt:
return errors.New("keyboard interrupt, closing")
case promptui.ErrEOF:
return errors.New("no input received, closing")
default:
return err
}
}