Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context: Remove Init/New #6797

Merged
merged 7 commits into from
Jul 20, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 0 additions & 125 deletions client/context.go
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -56,126 +51,6 @@ type Context struct {
Codec *codec.Codec
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me so happy ^__^

// 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
Expand Down
59 changes: 0 additions & 59 deletions client/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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())
Expand Down
60 changes: 27 additions & 33 deletions client/rpc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
}

Expand Down Expand Up @@ -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) {
Expand Down
42 changes: 18 additions & 24 deletions client/rpc/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"net/http"

"github.com/spf13/cobra"
"github.com/spf13/viper"

ctypes "github.com/tendermint/tendermint/rpc/core/types"

Expand All @@ -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
}

Expand All @@ -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 {
Expand All @@ -81,6 +74,7 @@ func NodeInfoRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
DefaultNodeInfo: status.NodeInfo,
ApplicationVersion: version.NewInfo(),
}

rest.PostProcessResponseBare(w, clientCtx, resp)
}
}
Expand Down
2 changes: 2 additions & 0 deletions server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ func interceptConfigs(ctx *Context, rootViper *viper.Viper) (*tmcfg.Config, erro
}
}

conf.SetRoot(rootDir)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @jgimeno - This fixes the issue you were seeing.


appConfigFilePath := filepath.Join(configPath, "app.toml")
if _, err := os.Stat(appConfigFilePath); os.IsNotExist(err) {
appConf, err := config.ParseConfig(ctx.Viper)
Expand Down
Loading