diff --git a/client/context.go b/client/context.go index 40a7c7c163d7..569aa45c1fde 100644 --- a/client/context.go +++ b/client/context.go @@ -1,24 +1,19 @@ package client import ( - "bufio" "encoding/json" - "fmt" "io" "os" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/pkg/errors" - "github.com/spf13/viper" yaml "gopkg.in/yaml.v2" - "github.com/tendermint/tendermint/libs/cli" tmlite "github.com/tendermint/tendermint/lite" rpcclient "github.com/tendermint/tendermint/rpc/client" rpchttp "github.com/tendermint/tendermint/rpc/client/http" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" @@ -56,126 +51,6 @@ type Context struct { Codec *codec.Codec } -// TODO: Remove all New* and Init* methods. - -// NewContextWithInputAndFrom returns a new initialized Context with parameters from the -// command line using Viper. It takes a io.Reader and and key name or address and populates -// the FromName and FromAddress field accordingly. It will also create Tendermint verifier -// using the chain ID, home directory and RPC URI provided by the command line. If using -// a Context in tests or any non CLI-based environment, the verifier will not be created -// and will be set as nil because FlagTrustNode must be set. -func NewContextWithInputAndFrom(input io.Reader, from string) Context { - ctx := Context{} - return ctx.InitWithInputAndFrom(input, from) -} - -// NewContextWithFrom returns a new initialized Context with parameters from the -// command line using Viper. It takes a key name or address and populates the FromName and -// FromAddress field accordingly. It will also create Tendermint verifier using -// the chain ID, home directory and RPC URI provided by the command line. If using -// a Context in tests or any non CLI-based environment, the verifier will not -// be created and will be set as nil because FlagTrustNode must be set. -func NewContextWithFrom(from string) Context { - return NewContextWithInputAndFrom(os.Stdin, from) -} - -// NewContext returns a new initialized Context with parameters from the -// command line using Viper. -func NewContext() Context { return NewContextWithFrom(viper.GetString(flags.FlagFrom)) } - -// InitWithInputAndFrom returns a new Context re-initialized from an existing -// Context with a new io.Reader and from parameter -func (ctx Context) InitWithInputAndFrom(input io.Reader, from string) Context { - input = bufio.NewReader(input) - - var ( - nodeURI string - rpc rpcclient.Client - err error - ) - - offline := viper.GetBool(flags.FlagOffline) - if !offline { - nodeURI = viper.GetString(flags.FlagNode) - if nodeURI != "" { - rpc, err = rpchttp.New(nodeURI, "/websocket") - if err != nil { - fmt.Printf("failted to get client: %v\n", err) - os.Exit(1) - } - } - } - - trustNode := viper.GetBool(flags.FlagTrustNode) - - ctx.Client = rpc - ctx.ChainID = viper.GetString(flags.FlagChainID) - ctx.Input = input - ctx.Output = os.Stdout - ctx.NodeURI = nodeURI - ctx.From = viper.GetString(flags.FlagFrom) - ctx.OutputFormat = viper.GetString(cli.OutputFlag) - ctx.Height = viper.GetInt64(flags.FlagHeight) - ctx.TrustNode = trustNode - ctx.UseLedger = viper.GetBool(flags.FlagUseLedger) - ctx.BroadcastMode = viper.GetString(flags.FlagBroadcastMode) - ctx.Simulate = viper.GetBool(flags.FlagDryRun) - ctx.Offline = offline - ctx.SkipConfirm = viper.GetBool(flags.FlagSkipConfirmation) - ctx.HomeDir = viper.GetString(flags.FlagHome) - ctx.GenerateOnly = viper.GetBool(flags.FlagGenerateOnly) - - backend := viper.GetString(flags.FlagKeyringBackend) - if len(backend) == 0 { - backend = keyring.BackendMemory - } - - kr, err := newKeyringFromFlags(ctx, backend) - if err != nil { - panic(fmt.Errorf("couldn't acquire keyring: %v", err)) - } - - fromAddress, fromName, err := GetFromFields(kr, from, ctx.GenerateOnly) - if err != nil { - fmt.Printf("failed to get from fields: %v\n", err) - os.Exit(1) - } - - ctx.Keyring = kr - ctx.FromAddress = fromAddress - ctx.FromName = fromName - - if offline { - return ctx - } - - // create a verifier for the specific chain ID and RPC client - verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) - if err != nil && !trustNode { - fmt.Printf("failed to create verifier: %s\n", err) - os.Exit(1) - } - - ctx.Verifier = verifier - return ctx -} - -// InitWithFrom returns a new Context re-initialized from an existing -// Context with a new from parameter -func (ctx Context) InitWithFrom(from string) Context { - return ctx.InitWithInputAndFrom(os.Stdin, from) -} - -// Init returns a new Context re-initialized from an existing -// Context with parameters from the command line using Viper. -func (ctx Context) Init() Context { return ctx.InitWithFrom(viper.GetString(flags.FlagFrom)) } - -// InitWithInput returns a new Context re-initialized from an existing -// Context with a new io.Reader and from parameter -func (ctx Context) InitWithInput(input io.Reader) Context { - return ctx.InitWithInputAndFrom(input, viper.GetString(flags.FlagFrom)) -} - // WithKeyring returns a copy of the context with an updated keyring. func (ctx Context) WithKeyring(k keyring.Keyring) Context { ctx.Keyring = k diff --git a/client/context_test.go b/client/context_test.go index 0027bcd0e73d..4b3498cffe6a 100644 --- a/client/context_test.go +++ b/client/context_test.go @@ -10,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/viper" "github.com/stretchr/testify/require" @@ -19,64 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" ) -func TestContext_WithOffline(t *testing.T) { - viper.Set(flags.FlagOffline, true) - viper.Set(flags.FlagNode, "tcp://localhost:26657") - - ctx := client.NewContext() - require.True(t, ctx.Offline) - require.Nil(t, ctx.Client) -} - -func TestContext_WithGenOnly(t *testing.T) { - viper.Set(flags.FlagGenerateOnly, true) - - validFromAddr := "cosmos1q7380u26f7ntke3facjmynajs4umlr329vr4ja" - fromAddr, err := sdk.AccAddressFromBech32(validFromAddr) - require.NoError(t, err) - - tests := []struct { - name string - from string - expectedFromAddr sdk.AccAddress - expectedFromName string - }{ - { - name: "valid from", - from: validFromAddr, - expectedFromAddr: fromAddr, - expectedFromName: "", - }, - { - name: "empty from", - from: "", - expectedFromAddr: nil, - expectedFromName: "", - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - ctx := client.NewContextWithFrom(tt.from) - - require.Equal(t, tt.expectedFromAddr, ctx.FromAddress) - require.Equal(t, tt.expectedFromName, ctx.FromName) - }) - } -} - -func TestContext_WithKeyring(t *testing.T) { - viper.Set(flags.FlagGenerateOnly, true) - ctx := client.NewContextWithFrom("cosmos1q7380u26f7ntke3facjmynajs4umlr329vr4ja") - require.NotNil(t, ctx.Keyring) - kr := ctx.Keyring - ctx = ctx.WithKeyring(nil) - require.Nil(t, ctx.Keyring) - ctx = ctx.WithKeyring(kr) - require.Equal(t, kr, ctx.Keyring) -} - func TestMain(m *testing.M) { viper.Set(flags.FlagKeyringBackend, keyring.BackendMemory) os.Exit(m.Run()) diff --git a/client/rpc/block.go b/client/rpc/block.go index 68fae1d8f554..7160dd635efe 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -7,7 +7,6 @@ import ( "github.com/gorilla/mux" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -23,14 +22,36 @@ func BlockCommand() *cobra.Command { Use: "block [height]", Short: "Get verified data for a the block at given height", Args: cobra.MaximumNArgs(1), - RunE: printBlock, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + var height *int64 + + // optional height + if len(args) > 0 { + h, err := strconv.Atoi(args[0]) + if err != nil { + return err + } + if h > 0 { + tmp := int64(h) + height = &tmp + } + } + + output, err := getBlock(clientCtx, height) + if err != nil { + return err + } + + fmt.Println(string(output)) + return nil + }, } + cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") - viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) cmd.Flags().Bool(flags.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") - viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") - viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend)) + return cmd } @@ -83,33 +104,6 @@ func GetChainHeight(clientCtx client.Context) (int64, error) { return height, nil } -// CMD - -func printBlock(cmd *cobra.Command, args []string) error { - var height *int64 - // optional height - if len(args) > 0 { - h, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - if h > 0 { - tmp := int64(h) - height = &tmp - } - } - - output, err := getBlock(client.NewContext(), height) - if err != nil { - return err - } - - fmt.Println(string(output)) - return nil -} - -// REST - // REST handler to get a block func BlockRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/client/rpc/status.go b/client/rpc/status.go index 918c49068c66..b946840afcc6 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -5,7 +5,6 @@ import ( "net/http" "github.com/spf13/cobra" - "github.com/spf13/viper" ctypes "github.com/tendermint/tendermint/rpc/core/types" @@ -23,11 +22,26 @@ func StatusCommand() *cobra.Command { cmd := &cobra.Command{ Use: "status", Short: "Query remote node for status", - RunE: printNodeStatus, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + status, err := getNodeStatus(clientCtx) + if err != nil { + return err + } + + output, err := legacy.Cdc.MarshalJSON(status) + if err != nil { + return err + } + + fmt.Println(string(output)) + return nil + }, } cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") - viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) + return cmd } @@ -40,27 +54,6 @@ func getNodeStatus(clientCtx client.Context) (*ctypes.ResultStatus, error) { return node.Status() } -func printNodeStatus(_ *cobra.Command, _ []string) error { - // No need to verify proof in getting node status - viper.Set(flags.FlagTrustNode, true) - // No need to verify proof in getting node status - viper.Set(flags.FlagKeyringBackend, flags.DefaultKeyringBackend) - - clientCtx := client.NewContext() - status, err := getNodeStatus(clientCtx) - if err != nil { - return err - } - - output, err := legacy.Cdc.MarshalJSON(status) - if err != nil { - return err - } - - fmt.Println(string(output)) - return nil -} - // NodeInfoResponse defines a response type that contains node status and version // information. type NodeInfoResponse struct { @@ -81,6 +74,7 @@ func NodeInfoRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { DefaultNodeInfo: status.NodeInfo, ApplicationVersion: version.NewInfo(), } + rest.PostProcessResponseBare(w, clientCtx, resp) } } diff --git a/server/util.go b/server/util.go index f2afd97e829e..7b329e49c09c 100644 --- a/server/util.go +++ b/server/util.go @@ -144,6 +144,8 @@ func interceptConfigs(ctx *Context, rootViper *viper.Viper) (*tmcfg.Config, erro } } + conf.SetRoot(rootDir) + appConfigFilePath := filepath.Join(configPath, "app.toml") if _, err := os.Stat(appConfigFilePath); os.IsNotExist(err) { appConf, err := config.ParseConfig(ctx.Viper) diff --git a/tests/cli/grpc_query_test.go b/tests/cli/grpc_query_test.go index 63c192d1bd6a..e3d89c9bcf53 100644 --- a/tests/cli/grpc_query_test.go +++ b/tests/cli/grpc_query_test.go @@ -1,5 +1,3 @@ -// +build cli_test - package cli import ( @@ -8,20 +6,18 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/testutil/network" "github.com/cosmos/cosmos-sdk/testutil/testdata" ) -func TestCliQueryConn(t *testing.T) { - t.Parallel() - f := NewFixtures(t) +func TestCLIQueryConn(t *testing.T) { + cfg := network.DefaultConfig() + cfg.NumValidators = 1 - // start simd server - proc := f.SDStart() - t.Cleanup(func() { proc.Stop(false) }) + n := network.New(t, cfg) + defer n.Cleanup() - ctx := client.NewContext() - testClient := testdata.NewTestServiceClient(ctx) + testClient := testdata.NewTestServiceClient(n.Validators[0].ClientCtx) res, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"}) require.NoError(t, err) require.Equal(t, "hello", res.Message) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 505c51f8176b..ef9cfff0e70a 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -188,7 +188,7 @@ func TestProcessPostResponse(t *testing.T) { // setup viper.Set(flags.FlagOffline, true) - ctx := client.NewContext() + ctx := client.Context{} height := int64(194423) privKey := secp256k1.GenPrivKey() diff --git a/x/evidence/client/cli/tx.go b/x/evidence/client/cli/tx.go index 934f46056b32..f13e3e8e2f65 100644 --- a/x/evidence/client/cli/tx.go +++ b/x/evidence/client/cli/tx.go @@ -12,7 +12,7 @@ import ( // modules, under a sub-command. This allows external modules to implement custom // Evidence types and Handlers while having the ability to create and sign txs // containing them all from a single root command. -func GetTxCmd(clientCtx client.Context, childCmds []*cobra.Command) *cobra.Command { +func GetTxCmd(childCmds []*cobra.Command) *cobra.Command { cmd := &cobra.Command{ Use: types.ModuleName, Short: "Evidence transaction subcommands", @@ -21,7 +21,7 @@ func GetTxCmd(clientCtx client.Context, childCmds []*cobra.Command) *cobra.Comma RunE: client.ValidateCmd, } - submitEvidenceCmd := SubmitEvidenceCmd(clientCtx) + submitEvidenceCmd := SubmitEvidenceCmd() for _, childCmd := range childCmds { submitEvidenceCmd.AddCommand(childCmd) } @@ -34,7 +34,7 @@ func GetTxCmd(clientCtx client.Context, childCmds []*cobra.Command) *cobra.Comma // SubmitEvidenceCmd returns the top-level evidence submission command handler. // All concrete evidence submission child command handlers should be registered // under this command. -func SubmitEvidenceCmd(_ client.Context) *cobra.Command { +func SubmitEvidenceCmd() *cobra.Command { cmd := &cobra.Command{ Use: "submit", Short: "Submit arbitrary evidence of misbehavior", diff --git a/x/evidence/client/evidence_handler.go b/x/evidence/client/evidence_handler.go index 4942d14805b6..7cada571ccc3 100644 --- a/x/evidence/client/evidence_handler.go +++ b/x/evidence/client/evidence_handler.go @@ -12,7 +12,7 @@ type ( RESTHandlerFn func(client.Context) rest.EvidenceRESTHandler // CLIHandlerFn defines a CLI command handler for evidence submission - CLIHandlerFn func(client.Context) *cobra.Command + CLIHandlerFn func() *cobra.Command // EvidenceHandler defines a type that exposes REST and CLI client handlers for // evidence submission. diff --git a/x/evidence/module.go b/x/evidence/module.go index 493998262364..ef76f6ccc714 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -86,14 +86,14 @@ func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Ro } // GetTxCmd returns the evidence module's root tx command. -func (a AppModuleBasic) GetTxCmd(clientCtx client.Context) *cobra.Command { +func (a AppModuleBasic) GetTxCmd(_ client.Context) *cobra.Command { evidenceCLIHandlers := make([]*cobra.Command, len(a.evidenceHandlers)) for i, evidenceHandler := range a.evidenceHandlers { - evidenceCLIHandlers[i] = evidenceHandler.CLIHandler(clientCtx) + evidenceCLIHandlers[i] = evidenceHandler.CLIHandler() } - return cli.GetTxCmd(clientCtx, evidenceCLIHandlers) + return cli.GetTxCmd(evidenceCLIHandlers) } // GetQueryCmd returns the evidence module's root query command. diff --git a/x/genutil/client/cli/init_test.go b/x/genutil/client/cli/init_test.go index aa862bd1d86c..cc5446cf7cb5 100644 --- a/x/genutil/client/cli/init_test.go +++ b/x/genutil/client/cli/init_test.go @@ -95,8 +95,7 @@ func TestInitCmd(t *testing.T) { } func setupClientHome(t *testing.T) func() { - clientDir, cleanup := testutil.NewTestCaseDir(t) - viper.Set(cli.HomeFlag, clientDir) + _, cleanup := testutil.NewTestCaseDir(t) return cleanup } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index b56e66d92422..ed71db655f7d 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -162,7 +162,11 @@ $ %s tx staking delegate cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 10 ), ), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := clientCtx.InitWithInput(cmd.InOrStdin()) + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } amount, err := sdk.ParseCoin(args[1]) if err != nil { @@ -204,7 +208,11 @@ $ %s tx staking redelegate cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj ), ), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := clientCtx.InitWithInput(cmd.InOrStdin()) + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } delAddr := clientCtx.GetFromAddress() valSrcAddr, err := sdk.ValAddressFromBech32(args[0]) @@ -251,7 +259,11 @@ $ %s tx staking unbond cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100s ), ), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := clientCtx.InitWithInput(cmd.InOrStdin()) + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } delAddr := clientCtx.GetFromAddress() valAddr, err := sdk.ValAddressFromBech32(args[0]) diff --git a/x/upgrade/client/cli/tx.go b/x/upgrade/client/cli/tx.go index 2e516a815cd9..437a998d924d 100644 --- a/x/upgrade/client/cli/tx.go +++ b/x/upgrade/client/cli/tx.go @@ -91,14 +91,19 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { } // NewCmdSubmitCancelUpgradeProposal implements a command handler for submitting a software upgrade cancel proposal transaction. -func NewCmdSubmitCancelUpgradeProposal(clientCtx client.Context) *cobra.Command { +func NewCmdSubmitCancelUpgradeProposal() *cobra.Command { cmd := &cobra.Command{ Use: "cancel-software-upgrade [flags]", Args: cobra.ExactArgs(0), Short: "Submit a software upgrade proposal", Long: "Cancel a software upgrade along with an initial deposit.", RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := clientCtx.InitWithInput(cmd.InOrStdin()) + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + from := clientCtx.GetFromAddress() depositStr, err := cmd.Flags().GetString(cli.FlagDeposit)