diff --git a/client/tx/root.go b/client/tx/root.go index e6c6786be..2099fb211 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -2,12 +2,19 @@ package tx import ( "github.com/spf13/cobra" + wire "github.com/tendermint/go-wire" ) +// type used to pass around the provided cdc +type commander struct { + cdc *wire.Codec +} + // AddCommands adds a number of tx-query related subcommands -func AddCommands(cmd *cobra.Command) { +func AddCommands(cmd *cobra.Command, cdc *wire.Codec) { + cmdr := commander{cdc} cmd.AddCommand( - txSearchCommand(), - txCommand(), + SearchTxCmd(cmdr), + QueryTxCmd(cmdr), ) } diff --git a/client/tx/search.go b/client/tx/search.go index adb3df32a..ffe0ca323 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -9,7 +9,7 @@ import ( "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/examples/basecoin/app" + wire "github.com/tendermint/go-wire" ctypes "github.com/tendermint/tendermint/rpc/core/types" ) @@ -18,21 +18,22 @@ const ( flagAny = "any" ) -func txSearchCommand() *cobra.Command { +// default client command to search through tagged transactions +func SearchTxCmd(cmdr commander) *cobra.Command { cmd := &cobra.Command{ Use: "txs", Short: "Search for all transactions that match the given tags", - RunE: searchTx, + RunE: cmdr.searchTxCmd, } cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") - // TODO: change this to false when we can + // TODO: change this to false once proofs built in cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") cmd.Flags().StringSlice(flagTags, nil, "Tags that must match (may provide multiple)") cmd.Flags().Bool(flagAny, false, "Return transactions that match ANY tag, rather than ALL") return cmd } -func searchTx(cmd *cobra.Command, args []string) error { +func (c commander) searchTxCmd(cmd *cobra.Command, args []string) error { tags := viper.GetStringSlice(flagTags) if len(tags) == 0 { return errors.New("Must declare at least one tag to search") @@ -52,13 +53,12 @@ func searchTx(cmd *cobra.Command, args []string) error { return err } - info, err := formatTxResults(res) + info, err := formatTxResults(c.cdc, res) if err != nil { return err } - cdc := app.MakeTxCodec() - output, err := cdc.MarshalJSON(info) + output, err := c.cdc.MarshalJSON(info) if err != nil { return err } @@ -67,11 +67,11 @@ func searchTx(cmd *cobra.Command, args []string) error { return nil } -func formatTxResults(res []*ctypes.ResultTx) ([]txInfo, error) { +func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) { var err error out := make([]txInfo, len(res)) for i := range res { - out[i], err = formatTxResult(res[i]) + out[i], err = formatTxResult(cdc, res[i]) if err != nil { return nil, err } diff --git a/client/tx/tx.go b/client/tx/tx.go index d79c341e6..9bf348dd0 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -9,18 +9,19 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/examples/basecoin/app" // XXX: not good + "github.com/cosmos/cosmos-sdk/client" // XXX: not good sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/abci/types" + wire "github.com/tendermint/go-wire" ctypes "github.com/tendermint/tendermint/rpc/core/types" ) -func txCommand() *cobra.Command { +// Get the default command for a tx query +func QueryTxCmd(cmdr commander) *cobra.Command { cmd := &cobra.Command{ - Use: "tx ", + Use: "tx [hash]", Short: "Matches this txhash over all committed blocks", - RunE: queryTx, + RunE: cmdr.queryTxCmd, } cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") // TODO: change this to false when we can @@ -29,7 +30,7 @@ func txCommand() *cobra.Command { } // command to query for a transaction -func queryTx(cmd *cobra.Command, args []string) error { +func (c commander) queryTxCmd(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { return errors.New("You must provide a tx hash") } @@ -52,7 +53,7 @@ func queryTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - info, err := formatTxResult(res) + info, err := formatTxResult(c.cdc, res) if err != nil { return err } @@ -66,9 +67,9 @@ func queryTx(cmd *cobra.Command, args []string) error { return nil } -func formatTxResult(res *ctypes.ResultTx) (txInfo, error) { +func formatTxResult(cdc *wire.Codec, res *ctypes.ResultTx) (txInfo, error) { // TODO: verify the proof if requested - tx, err := parseTx(res.Tx) + tx, err := parseTx(cdc, res.Tx) if err != nil { return txInfo{}, err } @@ -88,9 +89,8 @@ type txInfo struct { Result abci.ResponseDeliverTx `json:"result"` } -func parseTx(txBytes []byte) (sdk.Tx, error) { +func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { var tx sdk.StdTx - cdc := app.MakeTxCodec() err := cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, err diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 8e998c3ac..3c27faea9 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -4,6 +4,7 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -39,7 +40,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // create your application object var app = &BasecoinApp{ BaseApp: bam.NewBaseApp(appName, logger, db), - cdc: MakeTxCodec(), + cdc: MakeCodec(), capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), } @@ -70,9 +71,11 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { } // custom tx codec -func MakeTxCodec() *wire.Codec { +func MakeCodec() *wire.Codec { cdc := wire.NewCodec() - bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. + crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. return cdc } diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 49eb580fd..e917936b6 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -54,7 +54,7 @@ func TestSendMsg(t *testing.T) { }}) // just marshal/unmarshal! - cdc := MakeTxCodec() + cdc := MakeCodec() txBytes, err := cdc.MarshalBinary(tx) require.NoError(t, err) diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 6cabc2cef..638071d14 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,7 +14,11 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" + + "github.com/cosmos/cosmos-sdk/examples/basecoin/app" + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) // gaiacliCmd is the entry point for this binary @@ -33,20 +37,23 @@ func main() { // disable sorting cobra.EnableCommandSorting = false + // get the codec + cdc := app.MakeCodec() + // add standard rpc, and tx commands rpc.AddCommands(basecliCmd) basecliCmd.AddCommand(client.LineBreak) - tx.AddCommands(basecliCmd) + tx.AddCommands(basecliCmd, cdc) basecliCmd.AddCommand(client.LineBreak) // add query/post commands (custom to binary) basecliCmd.AddCommand( client.GetCommands( - bankcmd.GetAccountCmd("main"), + authcmd.GetAccountCmd("main", cdc, types.GetParseAccount(cdc)), )...) basecliCmd.AddCommand( client.PostCommands( - bankcmd.SendTxCommand(), + bankcmd.SendTxCmd(cdc), )...) // add proxy, version and key info diff --git a/examples/basecoin/types/account.go b/examples/basecoin/types/account.go index c9b1d8a23..f5b4f7aa0 100644 --- a/examples/basecoin/types/account.go +++ b/examples/basecoin/types/account.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" crypto "github.com/tendermint/go-crypto" + wire "github.com/tendermint/go-wire" ) var _ sdk.Account = (*AppAccount)(nil) @@ -22,6 +23,15 @@ type AppAccount struct { func (acc AppAccount) GetName() string { return acc.Name } func (acc *AppAccount) SetName(name string) { acc.Name = name } +// Get the ParseAccount function for the custom AppAccount +func GetParseAccount(cdc *wire.Codec) sdk.ParseAccount { + return func(accBytes []byte) (res sdk.Account, err error) { + acct := new(AppAccount) + err = cdc.UnmarshalBinary(accBytes, acct) + return acct, err + } +} + //___________________________________________________________________________________ // State to Unmarshal diff --git a/types/account.go b/types/account.go index d2dd9df6c..3a6e5931f 100644 --- a/types/account.go +++ b/types/account.go @@ -30,3 +30,6 @@ type AccountMapper interface { GetAccount(ctx Context, addr crypto.Address) Account SetAccount(ctx Context, acc Account) } + +// Application function variable used to unmarshal account +type ParseAccount func([]byte) (Account, error) diff --git a/x/auth/commands/account.go b/x/auth/commands/account.go new file mode 100644 index 000000000..2766c8ca1 --- /dev/null +++ b/x/auth/commands/account.go @@ -0,0 +1,82 @@ +package commands + +import ( + "encoding/hex" + "encoding/json" + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + + crypto "github.com/tendermint/go-crypto" + wire "github.com/tendermint/go-wire" + + "github.com/cosmos/cosmos-sdk/client" // XXX: not good + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +// GetAccountCmd for the auth.BaseAccount type +func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command { + return GetAccountCmd(storeName, cdc, getParseAccount(cdc)) +} + +func getParseAccount(cdc *wire.Codec) sdk.ParseAccount { + return func(accBytes []byte) (sdk.Account, error) { + acct := new(auth.BaseAccount) + err := cdc.UnmarshalBinary(accBytes, acct) + return acct, err + } +} + +// GetAccountCmd returns a query account that will display the +// state of the account at a given address +func GetAccountCmd(storeName string, cdc *wire.Codec, parser sdk.ParseAccount) *cobra.Command { + cmdr := commander{ + storeName, + cdc, + parser, + } + return &cobra.Command{ + Use: "account
", + Short: "Query account balance", + RunE: cmdr.getAccountCmd, + } +} + +type commander struct { + storeName string + cdc *wire.Codec + parser sdk.ParseAccount +} + +func (c commander) getAccountCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 || len(args[0]) == 0 { + return errors.New("You must provide an account name") + } + + // find the key to look up the account + addr := args[0] + bz, err := hex.DecodeString(addr) + if err != nil { + return err + } + key := crypto.Address(bz) + + res, err := client.Query(key, c.storeName) + + // parse out the value + account, err := c.parser(res) + if err != nil { + return err + } + + // print out whole account + output, err := json.MarshalIndent(account, "", " ") + if err != nil { + return err + } + fmt.Println(string(output)) + + return nil +} diff --git a/x/bank/commands/account.go b/x/bank/commands/account.go deleted file mode 100644 index ebe76e3ed..000000000 --- a/x/bank/commands/account.go +++ /dev/null @@ -1,73 +0,0 @@ -package commands - -import ( - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/pkg/errors" - "github.com/spf13/cobra" - - crypto "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" // XXX: not good - - "github.com/cosmos/cosmos-sdk/x/bank" -) - -// GetAccountCmd returns a query account that will display the -// state of the account at a given address -func GetAccountCmd(storeName string) *cobra.Command { - return &cobra.Command{ - Use: "account
", - Short: "Query account balance", - RunE: newRunner(storeName).cmd, - } -} - -type runner struct { - storeName string -} - -func newRunner(storeName string) runner { - return runner{ - storeName: storeName, - } -} - -func (r runner) cmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide an account name") - } - - // find the key to look up the account - addr := args[0] - bz, err := hex.DecodeString(addr) - if err != nil { - return err - } - key := crypto.Address(bz) - - res, err := client.Query(key, r.storeName) - - // parse out the value - acct := new(types.AppAccount) - cdc := wire.NewCodec() - bank.RegisterWire(cdc) - - err = cdc.UnmarshalBinary(res, acct) - if err != nil { - return err - } - - // print out whole account - output, err := json.MarshalIndent(acct, "", " ") - if err != nil { - return err - } - fmt.Println(string(output)) - - return nil -} diff --git a/x/bank/commands/sendtx.go b/x/bank/commands/sendtx.go index 65b8fb196..941b0b69f 100644 --- a/x/bank/commands/sendtx.go +++ b/x/bank/commands/sendtx.go @@ -26,11 +26,12 @@ const ( ) // SendTxCommand will create a send tx and sign it with the given key -func SendTxCommand() *cobra.Command { +func SendTxCmd(cdc *wire.Codec) *cobra.Command { + cmdr := commander{cdc} cmd := &cobra.Command{ Use: "send", Short: "Create and sign a send tx", - RunE: sendTx, + RunE: cmdr.sendTxCmd, } cmd.Flags().String(flagTo, "", "Address to send coins") cmd.Flags().String(flagAmount, "", "Amount of coins to send") @@ -39,8 +40,12 @@ func SendTxCommand() *cobra.Command { return cmd } -func sendTx(cmd *cobra.Command, args []string) error { - txBytes, err := buildTx() +type commander struct { + cdc *wire.Codec +} + +func (c commander) sendTxCmd(cmd *cobra.Command, args []string) error { + txBytes, err := c.buildTx() if err != nil { return err } @@ -54,7 +59,7 @@ func sendTx(cmd *cobra.Command, args []string) error { return nil } -func buildTx() ([]byte, error) { +func (c commander) buildTx() ([]byte, error) { keybase, err := keys.GetKeyBase() if err != nil { return nil, err @@ -92,10 +97,8 @@ func buildTx() ([]byte, error) { // marshal bytes tx := sdk.NewStdTx(msg, sigs) - cdc := wire.NewCodec() - bank.RegisterWire(cdc) - txBytes, err := cdc.MarshalBinary(tx) + txBytes, err := c.cdc.MarshalBinary(tx) if err != nil { return nil, err } diff --git a/x/bank/wire.go b/x/bank/wire.go index ee8391116..7162a416a 100644 --- a/x/bank/wire.go +++ b/x/bank/wire.go @@ -1,8 +1,6 @@ package bank import ( - sdk "github.com/cosmos/cosmos-sdk/types" - crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" ) @@ -10,8 +8,4 @@ func RegisterWire(cdc *wire.Codec) { // TODO include option to always include prefix bytes. cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/SendMsg", nil) cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/IssueMsg", nil) - - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - - crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. }