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

WIP client generalization #4296

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
24 changes: 24 additions & 0 deletions client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,27 @@ func saveConfigFile(cfgFile string, tree *toml.Tree) error {
func errUnknownConfigKey(key string) error {
return fmt.Errorf("unknown configuration key: %q", key)
}

// initialize the config command flags
func InitConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {
return err
}

cfgFile := path.Join(home, "config", "config.toml")
if _, err := os.Stat(cfgFile); err == nil {
viper.SetConfigFile(cfgFile)

if err := viper.ReadInConfig(); err != nil {
return err
}
}
if err := viper.BindPFlag(FlagChainID, cmd.PersistentFlags().Lookup(FlagChainID)); err != nil {
return err
}
if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil {
return err
}
return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag))
}
12 changes: 6 additions & 6 deletions client/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/codec"
cryptokeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/x/auth"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

"github.com/spf13/viper"

Expand All @@ -35,7 +35,7 @@ var (
// transaction handling and queries.
type CLIContext struct {
Codec *codec.Codec
AccDecoder auth.AccountDecoder
AccDecoder authtypes.AccountDecoder
Client rpcclient.Client
Keybase cryptokeys.Keybase
Output io.Writer
Expand Down Expand Up @@ -89,7 +89,7 @@ func NewCLIContextWithFrom(from string) CLIContext {
Client: rpc,
Output: os.Stdout,
NodeURI: nodeURI,
AccountStore: auth.StoreKey,
AccountStore: authtypes.StoreKey,
From: viper.GetString(client.FlagFrom),
OutputFormat: viper.GetString(cli.OutputFlag),
Height: viper.GetInt64(client.FlagHeight),
Expand Down Expand Up @@ -163,9 +163,9 @@ func (ctx CLIContext) WithCodec(cdc *codec.Codec) CLIContext {
return ctx
}

// GetAccountDecoder gets the account decoder for auth.DefaultAccount.
func GetAccountDecoder(cdc *codec.Codec) auth.AccountDecoder {
return func(accBytes []byte) (acct auth.Account, err error) {
// GetAccountDecoder gets the account decoder for authtypes.DefaultAccount.
func GetAccountDecoder(cdc *codec.Codec) authtypes.AccountDecoder {
return func(accBytes []byte) (acct authtypes.Account, err error) {
err = cdc.UnmarshalBinaryBare(accBytes, &acct)
if err != nil {
panic(err)
Expand Down
5 changes: 3 additions & 2 deletions client/context/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

"github.com/pkg/errors"

Expand Down Expand Up @@ -61,7 +62,7 @@ func (ctx CLIContext) QuerySubspace(subspace []byte, storeName string) (res []sd

// GetAccount queries for an account given an address and a block height. An
// error is returned if the query or decoding fails.
func (ctx CLIContext) GetAccount(address []byte) (auth.Account, error) {
func (ctx CLIContext) GetAccount(address []byte) (authtypes.Account, error) {
if ctx.AccDecoder == nil {
return nil, errors.New("account decoder required but not provided")
}
Expand All @@ -71,7 +72,7 @@ func (ctx CLIContext) GetAccount(address []byte) (auth.Account, error) {
return nil, err
}

var account auth.Account
var account authtypes.Account
if err := ctx.Codec.UnmarshalJSON(res, &account); err != nil {
return nil, err
}
Expand Down
19 changes: 19 additions & 0 deletions client/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package client

import (
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli"
)

// PrepareMainCmd is meant for client side libs that want some more flags
func PrepareMainCmd(cmd *cobra.Command, envPrefix, defaultHome string) Executor {

// Add --chain-id to persistent flags and mark it required
rootCmd.PersistentFlags().String(FlagChainID, "", "Chain ID of tendermint node")
rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
return InitConfig(rootCmd)
}

// add tendermint setup
return cli.PrepareMainCmd(cmd, envPrefix, defaultHome)
}
2 changes: 1 addition & 1 deletion cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func init() {
staking.AppModuleBasic{},
mint.AppModuleBasic{},
distr.AppModuleBasic{},
gov.AppModuleBasic{},
gov.NewAppModuleBasic(paramcli.GetCmdSubmitProposal()),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
slashing.AppModuleBasic{},
Expand Down
71 changes: 15 additions & 56 deletions cmd/gaia/cmd/gaiacli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"net/http"
"os"
"path"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
Expand Down Expand Up @@ -40,10 +39,8 @@ import (

"github.com/rakyll/statik/fs"
"github.com/spf13/cobra"
"github.com/spf13/viper"

amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/libs/cli"

_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
)
Expand All @@ -66,6 +63,7 @@ func main() {
// the below functions and eliminate global vars, like we do
// with the cdc

// XXX abstract this
// Module clients hold cli commnads (tx,query) and lcd routes
// TODO: Make the lcd command take a list of ModuleClient
mc := []sdk.ModuleClient{
Expand All @@ -82,18 +80,12 @@ func main() {
Short: "Command line interface for interacting with gaiad",
}

// Add --chain-id to persistent flags and mark it required
rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node")
rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
return initConfig(rootCmd)
}

// Construct Root Command
rootCmd.AddCommand(
rpc.StatusCommand(),
client.ConfigCmd(app.DefaultCLIHome),
queryCmd(cdc, mc),
txCmd(cdc, mc),
queryCmd(cdc, app.BasicGaiaApp),
txCmd(cdc, app.BasicGaiaApp),
client.LineBreak,
lcd.ServeCommand(cdc, registerRoutes),
client.LineBreak,
Expand All @@ -104,7 +96,7 @@ func main() {
)

// Add flags and prefix all env exposed with GA
executor := cli.PrepareMainCmd(rootCmd, "GA", app.DefaultCLIHome)
executor := client.PrepareMainCmd(rootCmd, "GA", app.DefaultCLIHome)

err := executor.Execute()
if err != nil {
Expand All @@ -113,13 +105,12 @@ func main() {
}
}

func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClient) *cobra.Command {
func queryCmd(cdc *amino.Codec, mbm sdk.ModuleBasicManager) *cobra.Command {
queryCmd := &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Querying subcommands",
}

queryCmd.AddCommand(
rpc.ValidatorCommand(cdc),
rpc.BlockCommand(),
Expand All @@ -128,23 +119,15 @@ func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClient) *cobra.Command {
client.LineBreak,
authcmd.GetAccountCmd(at.StoreKey, cdc),
)

for _, m := range mc {
mQueryCmd := m.GetQueryCmd()
if mQueryCmd != nil {
queryCmd.AddCommand(mQueryCmd)
}
}

mbm.AddQueryCommands(txCmd)
return queryCmd
}

func txCmd(cdc *amino.Codec, mc []sdk.ModuleClient) *cobra.Command {
func txCmd(cdc *amino.Codec, mbm sdk.ModuleBasicManager) *cobra.Command {
txCmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
}

txCmd.AddCommand(
bankcmd.SendTxCmd(cdc),
client.LineBreak,
Expand All @@ -154,26 +137,25 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClient) *cobra.Command {
tx.GetEncodeCommand(cdc),
client.LineBreak,
)

for _, m := range mc {
txCmd.AddCommand(m.GetTxCmd())
}

mbm.AddTxCommands(txCmd)
return txCmd
}

// registerRoutes registers the routes from the different modules for the LCD.
// NOTE: details on the routes added for each module are in the module documentation
// NOTE: If making updates here you also need to update the test helper in client/lcd/test_helper.go
func registerRoutes(rs *lcd.RestServer) {
func registerRoutes(rs *lcd.RestServer, mbm sdk.ModuleBasicManager) {
registerSwaggerUI(rs)
rpc.RegisterRoutes(rs.CliCtx, rs.Mux)
tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
mbm.RegisterRESTRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)

// XXX Abstract this
auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, at.StoreKey)
bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
dist.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distcmd.StoreKey)
staking.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
staking.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
gov.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, paramsrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc))
mintrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
}
Expand All @@ -186,26 +168,3 @@ func registerSwaggerUI(rs *lcd.RestServer) {
staticServer := http.FileServer(statikFS)
rs.Mux.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", staticServer))
}

func initConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {
return err
}

cfgFile := path.Join(home, "config", "config.toml")
if _, err := os.Stat(cfgFile); err == nil {
viper.SetConfigFile(cfgFile)

if err := viper.ReadInConfig(); err != nil {
return err
}
}
if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil {
return err
}
if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil {
return err
}
return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag))
}
41 changes: 35 additions & 6 deletions types/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,28 @@ ModuleBasicManager.
package types

import (
"context"
"encoding/json"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types"
)

// ModuleClient helps modules provide a standard interface for exporting client functionality
type ModuleClient interface {
GetQueryCmd() *cobra.Command
GetTxCmd() *cobra.Command
}

//__________________________________________________________________________________________
// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
Name() string
RegisterCodec(*codec.Codec)

// genesis
DefaultGenesis() json.RawMessage
ValidateGenesis(json.RawMessage) error

// client functionality
RegisterRESTRoutes(context.CLIContext, *mux.Router, *codec.Codec)
GetTxCmd() *cobra.Command
GetQueryCmd() *cobra.Command
}

// collections of AppModuleBasic
Expand Down Expand Up @@ -77,6 +79,33 @@ func (mbm ModuleBasicManager) ValidateGenesis(genesis map[string]json.RawMessage
return nil
}

// RegisterRestRoutes registers all module rest routes
func (mbm ModuleBasicManager) RegisterRESTRoutes(
ctx context.CLIContext, rtr *mux.Router, cdc *codec.Codec) {

for _, mb := range mbm {
mb.RegisterRESTRoutes(ctx, rtr, cdc)
}
}

// add all tx commands to the rootTxCmd
func (mbm ModuleBasicManager) AddTxCommands(rootTxCmd *cobra.Command) {
for _, mb := range mbm {
if cmd := mb.GetTxCmd(); cmd != nil {
rootTxCmd.AddCommand(cmd)
}
}
}

// add all query commands to the rootQueryCmd
func (mbm ModuleBasicManager) AddQueryCommands(rootQueryCmd *cobra.Command) {
for _, mb := range mbm {
if cmd := mb.GetQueryCmd(); cmd != nil {
rootQueryCmd.AddCommand(cmd)
}
}
}

//_________________________________________________________
// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
Expand Down
Loading