diff --git a/cmd/basecli/commands/auto.go b/client/commands/auto/cmd.go similarity index 97% rename from cmd/basecli/commands/auto.go rename to client/commands/auto/cmd.go index 040eb6ac3..704ba1785 100644 --- a/cmd/basecli/commands/auto.go +++ b/client/commands/auto/cmd.go @@ -1,4 +1,4 @@ -package commands +package auto import ( "os" diff --git a/client/commands/common.go b/client/commands/common.go index a022ff408..f14a11f38 100644 --- a/client/commands/common.go +++ b/client/commands/common.go @@ -4,18 +4,23 @@ Package commands contains any general setup/helpers valid for all subcommands package commands import ( - "errors" + "encoding/hex" + "strings" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/tmlibs/cli" - - rpcclient "github.com/tendermint/tendermint/rpc/client" - "github.com/tendermint/light-client/certifiers" "github.com/tendermint/light-client/certifiers/client" "github.com/tendermint/light-client/certifiers/files" + "github.com/tendermint/tmlibs/cli" + cmn "github.com/tendermint/tmlibs/common" + + rpcclient "github.com/tendermint/tendermint/rpc/client" + + "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/modules/auth" ) var ( @@ -28,19 +33,24 @@ const ( NodeFlag = "node" ) +// AddBasicFlags adds --node and --chain-id, which we need for everything func AddBasicFlags(cmd *cobra.Command) { cmd.PersistentFlags().String(ChainFlag, "", "Chain ID of tendermint node") cmd.PersistentFlags().String(NodeFlag, "", ": to tendermint rpc interface for this chain") } +// GetChainID reads ChainID from the flags func GetChainID() string { return viper.GetString(ChainFlag) } +// GetNode prepares a simple rpc.Client from the flags func GetNode() rpcclient.Client { return rpcclient.NewHTTP(viper.GetString(NodeFlag), "/websocket") } +// GetProviders creates a trusted (local) seed provider and a remote +// provider based on configuration. func GetProviders() (trusted certifiers.Provider, source certifiers.Provider) { if trustedProv == nil || sourceProv == nil { // initialize provider with files stored in homedir @@ -55,6 +65,7 @@ func GetProviders() (trusted certifiers.Provider, source certifiers.Provider) { return trustedProv, sourceProv } +// GetCertifier constructs a dynamic certifier from the config info func GetCertifier() (*certifiers.InquiringCertifier, error) { // load up the latest store.... trust, source := GetProviders() @@ -71,3 +82,35 @@ func GetCertifier() (*certifiers.InquiringCertifier, error) { viper.GetString(ChainFlag), seed.Validators, trust, source) return cert, nil } + +// ParseAddress parses an address of form: +// [:][:] +// into a basecoin.Actor. +// If app is not specified or "", then assume auth.NameSigs +func ParseAddress(input string) (res basecoin.Actor, err error) { + chain, app := "", auth.NameSigs + input = strings.TrimSpace(input) + spl := strings.SplitN(input, ":", 3) + + if len(spl) == 3 { + chain = spl[0] + spl = spl[1:] + } + if len(spl) == 2 { + if spl[0] != "" { + app = spl[0] + } + spl = spl[1:] + } + + addr, err := hex.DecodeString(cmn.StripHex(spl[0])) + if err != nil { + return res, errors.Errorf("Address is invalid hex: %v\n", err) + } + res = basecoin.Actor{ + ChainID: chain, + App: app, + Address: addr, + } + return +} diff --git a/client/commands/txs/helpers.go b/client/commands/txs/helpers.go index 3a592a450..dd7999dd7 100644 --- a/client/commands/txs/helpers.go +++ b/client/commands/txs/helpers.go @@ -14,16 +14,19 @@ import ( "github.com/pkg/errors" "github.com/spf13/viper" - "github.com/tendermint/basecoin/client/commands" crypto "github.com/tendermint/go-crypto" keycmd "github.com/tendermint/go-crypto/cmd" "github.com/tendermint/go-crypto/keys" + lc "github.com/tendermint/light-client" ctypes "github.com/tendermint/tendermint/rpc/core/types" - lc "github.com/tendermint/light-client" + "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/client/commands" + "github.com/tendermint/basecoin/modules/auth" ) +// Validatable represents anything that can be Validated type Validatable interface { ValidateBasic() error } @@ -37,6 +40,17 @@ func GetSigner() crypto.PubKey { return info.PubKey } +// GetSignerAct returns the address of the signer of the tx +// (as we still only support single sig) +func GetSignerAct() (res basecoin.Actor) { + // this could be much cooler with multisig... + signer := GetSigner() + if !signer.Empty() { + res = auth.SigPerm(signer.Address()) + } + return res +} + // Sign if it is Signable, otherwise, just convert it to bytes func Sign(tx interface{}) (packet []byte, err error) { name := viper.GetString(NameFlag) diff --git a/client/commands/txs/presenter.go b/client/commands/txs/presenter.go new file mode 100644 index 000000000..b13f694e5 --- /dev/null +++ b/client/commands/txs/presenter.go @@ -0,0 +1,34 @@ +package txs + +import ( + "github.com/pkg/errors" + wire "github.com/tendermint/go-wire" + "github.com/tendermint/light-client/proofs" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + + "github.com/tendermint/basecoin" +) + +// BaseTxPresenter this decodes all basecoin tx +type BaseTxPresenter struct { + proofs.RawPresenter // this handles MakeKey as hex bytes +} + +// ParseData - unmarshal raw bytes to a basecoin tx +func (BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { + var tx basecoin.Tx + err := wire.ReadBinaryBytes(raw, &tx) + return tx, err +} + +// ValidateResult returns an appropriate error if the server rejected the +// tx in CheckTx or DeliverTx +func ValidateResult(res *ctypes.ResultBroadcastTxCommit) error { + if res.CheckTx.IsErr() { + return errors.Errorf("CheckTx: (%d): %s", res.CheckTx.Code, res.CheckTx.Log) + } + if res.DeliverTx.IsErr() { + return errors.Errorf("DeliverTx: (%d): %s", res.DeliverTx.Code, res.DeliverTx.Log) + } + return nil +} diff --git a/client/commands/txs/wrapper.go b/client/commands/txs/wrapper.go new file mode 100644 index 000000000..3d711f948 --- /dev/null +++ b/client/commands/txs/wrapper.go @@ -0,0 +1,45 @@ +package txs + +import ( + "github.com/spf13/pflag" + + "github.com/tendermint/basecoin" +) + +var ( + // Middleware must be set in main.go to defined the wrappers we should apply + Middleware Wrapper +) + +// Wrapper defines the information needed for each middleware package that +// wraps the data. They should read all configuration out of bounds via viper. +type Wrapper interface { + Wrap(basecoin.Tx) (basecoin.Tx, error) + Register(*pflag.FlagSet) +} + +// Wrappers combines a list of wrapper middlewares. +// The first one is the inner-most layer, eg. Fee, Nonce, Chain, Auth +type Wrappers []Wrapper + +var _ Wrapper = Wrappers{} + +// Wrap applies the wrappers to the passed in tx in order, +// aborting on the first error +func (ws Wrappers) Wrap(tx basecoin.Tx) (basecoin.Tx, error) { + var err error + for _, w := range ws { + tx, err = w.Wrap(tx) + if err != nil { + break + } + } + return tx, err +} + +// Register adds any needed flags to the command +func (ws Wrappers) Register(fs *pflag.FlagSet) { + for _, w := range ws { + w.Register(fs) + } +} diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go deleted file mode 100644 index c0ba9a6e0..000000000 --- a/cmd/basecli/commands/cmds.go +++ /dev/null @@ -1,111 +0,0 @@ -package commands - -import ( - "encoding/hex" - "fmt" - "strings" - - "github.com/pkg/errors" - "github.com/spf13/pflag" - - txcmd "github.com/tendermint/basecoin/client/commands/txs" - cmn "github.com/tendermint/tmlibs/common" - - ctypes "github.com/tendermint/tendermint/rpc/core/types" - - "github.com/tendermint/basecoin" - "github.com/tendermint/basecoin/modules/auth" -) - -var ( - // Middleware must be set in main.go to defined the wrappers we should apply - Middleware Wrapper -) - -// Wrapper defines the information needed for each middleware package that -// wraps the data. They should read all configuration out of bounds via viper. -type Wrapper interface { - Wrap(basecoin.Tx) (basecoin.Tx, error) - Register(*pflag.FlagSet) -} - -// Wrappers combines a list of wrapper middlewares. -// The first one is the inner-most layer, eg. Fee, Nonce, Chain, Auth -type Wrappers []Wrapper - -var _ Wrapper = Wrappers{} - -// Wrap applies the wrappers to the passed in tx in order, -// aborting on the first error -func (ws Wrappers) Wrap(tx basecoin.Tx) (basecoin.Tx, error) { - var err error - for _, w := range ws { - tx, err = w.Wrap(tx) - if err != nil { - break - } - } - return tx, err -} - -// Register adds any needed flags to the command -func (ws Wrappers) Register(fs *pflag.FlagSet) { - for _, w := range ws { - w.Register(fs) - } -} - -// ValidateResult returns an appropriate error if the server rejected the -// tx in CheckTx or DeliverTx -func ValidateResult(res *ctypes.ResultBroadcastTxCommit) error { - if res.CheckTx.IsErr() { - return fmt.Errorf("CheckTx: (%d): %s", res.CheckTx.Code, res.CheckTx.Log) - } - if res.DeliverTx.IsErr() { - return fmt.Errorf("DeliverTx: (%d): %s", res.DeliverTx.Code, res.DeliverTx.Log) - } - return nil -} - -// ParseAddress parses an address of form: -// [:][:] -// into a basecoin.Actor. -// If app is not specified or "", then assume auth.NameSigs -func ParseAddress(input string) (res basecoin.Actor, err error) { - chain, app := "", auth.NameSigs - input = strings.TrimSpace(input) - spl := strings.SplitN(input, ":", 3) - - if len(spl) == 3 { - chain = spl[0] - spl = spl[1:] - } - if len(spl) == 2 { - if spl[0] != "" { - app = spl[0] - } - spl = spl[1:] - } - - addr, err := hex.DecodeString(cmn.StripHex(spl[0])) - if err != nil { - return res, errors.Errorf("Address is invalid hex: %v\n", err) - } - res = basecoin.Actor{ - ChainID: chain, - App: app, - Address: addr, - } - return -} - -// GetSignerAct returns the address of the signer of the tx -// (as we still only support single sig) -func GetSignerAct() (res basecoin.Actor) { - // this could be much cooler with multisig... - signer := txcmd.GetSigner() - if !signer.Empty() { - res = auth.SigPerm(signer.Address()) - } - return res -} diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go deleted file mode 100644 index 2fd85a6c7..000000000 --- a/cmd/basecli/commands/query.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -import ( - wire "github.com/tendermint/go-wire" - "github.com/tendermint/light-client/proofs" - - "github.com/tendermint/basecoin" -) - -// BaseTxPresenter this decodes all basecoin tx -type BaseTxPresenter struct { - proofs.RawPresenter // this handles MakeKey as hex bytes -} - -// ParseData - unmarshal raw bytes to a basecoin tx -func (BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { - var tx basecoin.Tx - err := wire.ReadBinaryBytes(raw, &tx) - return tx, err -} diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 491c5cbee..b827f7ffb 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -8,15 +8,15 @@ import ( "github.com/tendermint/abci/version" keycmd "github.com/tendermint/go-crypto/cmd" + "github.com/tendermint/tmlibs/cli" + "github.com/tendermint/basecoin/client/commands" + "github.com/tendermint/basecoin/client/commands/auto" "github.com/tendermint/basecoin/client/commands/proofs" "github.com/tendermint/basecoin/client/commands/proxy" rpccmd "github.com/tendermint/basecoin/client/commands/rpc" "github.com/tendermint/basecoin/client/commands/seeds" - "github.com/tendermint/basecoin/client/commands/txs" - "github.com/tendermint/tmlibs/cli" - - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" authcmd "github.com/tendermint/basecoin/modules/auth/commands" basecmd "github.com/tendermint/basecoin/modules/base/commands" coincmd "github.com/tendermint/basecoin/modules/coin/commands" @@ -56,19 +56,19 @@ func main() { coincmd.AccountQueryCmd, noncecmd.NonceQueryCmd, ) + proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{}) // set up the middleware - bcmd.Middleware = bcmd.Wrappers{ + txcmd.Middleware = txcmd.Wrappers{ feecmd.FeeWrapper{}, noncecmd.NonceWrapper{}, basecmd.ChainWrapper{}, authcmd.SigWrapper{}, } - bcmd.Middleware.Register(txs.RootCmd.PersistentFlags()) + txcmd.Middleware.Register(txcmd.RootCmd.PersistentFlags()) // you will always want this for the base send command - proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) - txs.RootCmd.AddCommand( + txcmd.RootCmd.AddCommand( // This is the default transaction, optional in your app coincmd.SendTxCmd, ) @@ -81,10 +81,10 @@ func main() { seeds.RootCmd, rpccmd.RootCmd, proofs.RootCmd, - txs.RootCmd, + txcmd.RootCmd, proxy.RootCmd, VersionCmd, - bcmd.AutoCompleteCmd, + auto.AutoCompleteCmd, ) cmd := cli.PrepareMainCmd(BaseCli, "BC", os.ExpandEnv("$HOME/.basecli")) diff --git a/docs/guide/counter/cmd/countercli/commands/counter.go b/docs/guide/counter/cmd/countercli/commands/counter.go index bb66d4c07..a8e473276 100644 --- a/docs/guide/counter/cmd/countercli/commands/counter.go +++ b/docs/guide/counter/cmd/countercli/commands/counter.go @@ -4,10 +4,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - txcmd "github.com/tendermint/basecoin/client/commands/txs" - "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" "github.com/tendermint/basecoin/docs/guide/counter/plugins/counter" "github.com/tendermint/basecoin/modules/coin" ) @@ -43,7 +41,7 @@ func counterTx(cmd *cobra.Command, args []string) error { return err } - tx, err = bcmd.Middleware.Wrap(tx) + tx, err = txcmd.Middleware.Wrap(tx) if err != nil { return err } @@ -53,7 +51,7 @@ func counterTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - if err = bcmd.ValidateResult(bres); err != nil { + if err = txcmd.ValidateResult(bres); err != nil { return err } diff --git a/docs/guide/counter/cmd/countercli/main.go b/docs/guide/counter/cmd/countercli/main.go index 8440372f7..8cc95f667 100644 --- a/docs/guide/counter/cmd/countercli/main.go +++ b/docs/guide/counter/cmd/countercli/main.go @@ -6,14 +6,13 @@ import ( "github.com/spf13/cobra" keycmd "github.com/tendermint/go-crypto/cmd" + "github.com/tendermint/tmlibs/cli" + "github.com/tendermint/basecoin/client/commands" "github.com/tendermint/basecoin/client/commands/proofs" "github.com/tendermint/basecoin/client/commands/proxy" "github.com/tendermint/basecoin/client/commands/seeds" - "github.com/tendermint/basecoin/client/commands/txs" - "github.com/tendermint/tmlibs/cli" - - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" bcount "github.com/tendermint/basecoin/docs/guide/counter/cmd/countercli/commands" authcmd "github.com/tendermint/basecoin/modules/auth/commands" basecmd "github.com/tendermint/basecoin/modules/base/commands" @@ -50,17 +49,17 @@ func main() { ) // set up the middleware - bcmd.Middleware = bcmd.Wrappers{ + txcmd.Middleware = txcmd.Wrappers{ feecmd.FeeWrapper{}, noncecmd.NonceWrapper{}, basecmd.ChainWrapper{}, authcmd.SigWrapper{}, } - bcmd.Middleware.Register(txs.RootCmd.PersistentFlags()) + txcmd.Middleware.Register(txcmd.RootCmd.PersistentFlags()) // Prepare transactions - proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) - txs.RootCmd.AddCommand( + proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{}) + txcmd.RootCmd.AddCommand( // This is the default transaction, optional in your app coincmd.SendTxCmd, @@ -75,7 +74,7 @@ func main() { keycmd.RootCmd, seeds.RootCmd, proofs.RootCmd, - txs.RootCmd, + txcmd.RootCmd, proxy.RootCmd, ) diff --git a/modules/auth/commands/wrap.go b/modules/auth/commands/wrap.go index a02033c65..c93eecb70 100644 --- a/modules/auth/commands/wrap.go +++ b/modules/auth/commands/wrap.go @@ -5,7 +5,7 @@ import ( "github.com/spf13/viper" "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" "github.com/tendermint/basecoin/modules/auth" ) @@ -17,7 +17,7 @@ const ( // SigWrapper wraps a tx with a signature layer to hold pubkey sigs type SigWrapper struct{} -var _ bcmd.Wrapper = SigWrapper{} +var _ txcmd.Wrapper = SigWrapper{} // Wrap will wrap the tx with OneSig or MultiSig depending on flags func (SigWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) { diff --git a/modules/base/commands/wrap.go b/modules/base/commands/wrap.go index 13b6b7f34..e199c4ed0 100644 --- a/modules/base/commands/wrap.go +++ b/modules/base/commands/wrap.go @@ -9,7 +9,7 @@ import ( "github.com/tendermint/basecoin/client/commands" "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" "github.com/tendermint/basecoin/modules/base" ) @@ -21,7 +21,7 @@ const ( // ChainWrapper wraps a tx with an chain info and optional expiration type ChainWrapper struct{} -var _ bcmd.Wrapper = ChainWrapper{} +var _ txcmd.Wrapper = ChainWrapper{} // Wrap will wrap the tx with a ChainTx from the standard flags func (ChainWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) { diff --git a/modules/coin/commands/tx.go b/modules/coin/commands/tx.go index 4fd7037cf..9a338582c 100644 --- a/modules/coin/commands/tx.go +++ b/modules/coin/commands/tx.go @@ -4,11 +4,9 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/tendermint/basecoin" "github.com/tendermint/basecoin/client/commands" txcmd "github.com/tendermint/basecoin/client/commands/txs" - - "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" "github.com/tendermint/basecoin/modules/coin" ) @@ -47,7 +45,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { return err } - tx, err = bcmd.Middleware.Wrap(tx) + tx, err = txcmd.Middleware.Wrap(tx) if err != nil { return err } @@ -57,7 +55,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - if err = bcmd.ValidateResult(bres); err != nil { + if err = txcmd.ValidateResult(bres); err != nil { return err } @@ -67,7 +65,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { func readSendTxFlags() (tx basecoin.Tx, err error) { // parse to address - toAddr, err := bcmd.ParseAddress(viper.GetString(FlagTo)) + toAddr, err := commands.ParseAddress(viper.GetString(FlagTo)) if err != nil { return tx, err } @@ -98,7 +96,7 @@ func readSendTxFlags() (tx basecoin.Tx, err error) { func readFromAddr() (basecoin.Actor, error) { from := viper.GetString(FlagFrom) if from == "" { - return bcmd.GetSignerAct(), nil + return txcmd.GetSignerAct(), nil } - return bcmd.ParseAddress(from) + return commands.ParseAddress(from) } diff --git a/modules/fee/commands/wrap.go b/modules/fee/commands/wrap.go index c464c15c9..6f8c082f8 100644 --- a/modules/fee/commands/wrap.go +++ b/modules/fee/commands/wrap.go @@ -5,7 +5,8 @@ import ( "github.com/spf13/viper" "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + "github.com/tendermint/basecoin/client/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" "github.com/tendermint/basecoin/modules/coin" "github.com/tendermint/basecoin/modules/fee" ) @@ -19,7 +20,7 @@ const ( // FeeWrapper wraps a tx with an optional fee payment type FeeWrapper struct{} -var _ bcmd.Wrapper = FeeWrapper{} +var _ txcmd.Wrapper = FeeWrapper{} // Wrap checks for FlagFee and if present wraps the tx with a // FeeTx of the given amount, paid by the signer @@ -52,7 +53,7 @@ func (FeeWrapper) Register(fs *pflag.FlagSet) { func readPayer() (basecoin.Actor, error) { payer := viper.GetString(FlagPayer) if payer == "" { - return bcmd.GetSignerAct(), nil + return txcmd.GetSignerAct(), nil } - return bcmd.ParseAddress(payer) + return commands.ParseAddress(payer) } diff --git a/modules/nonce/commands/wrap.go b/modules/nonce/commands/wrap.go index 7e29e8312..bd3cc9999 100644 --- a/modules/nonce/commands/wrap.go +++ b/modules/nonce/commands/wrap.go @@ -8,7 +8,8 @@ import ( "github.com/spf13/viper" "github.com/tendermint/basecoin" - bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + "github.com/tendermint/basecoin/client/commands" + txcmd "github.com/tendermint/basecoin/client/commands/txs" "github.com/tendermint/basecoin/modules/nonce" ) @@ -21,7 +22,7 @@ const ( // NonceWrapper wraps a tx with a nonce type NonceWrapper struct{} -var _ bcmd.Wrapper = NonceWrapper{} +var _ txcmd.Wrapper = NonceWrapper{} // Wrap grabs the sequence number from the flag and wraps // the tx with this nonce. Grabs the permission from the signer, @@ -49,7 +50,7 @@ func (NonceWrapper) Register(fs *pflag.FlagSet) { func readNonceKey() ([]basecoin.Actor, error) { nonce := viper.GetString(FlagNonceKey) if nonce == "" { - return []basecoin.Actor{bcmd.GetSignerAct()}, nil + return []basecoin.Actor{txcmd.GetSignerAct()}, nil } return parseActors(nonce) } @@ -57,7 +58,7 @@ func readNonceKey() ([]basecoin.Actor, error) { func parseActors(key string) (signers []basecoin.Actor, err error) { var act basecoin.Actor for _, k := range strings.Split(key, ",") { - act, err = bcmd.ParseAddress(k) + act, err = commands.ParseAddress(k) if err != nil { return }