From 25e7a79174f5f078ab93b2cc85a9b07b545790c2 Mon Sep 17 00:00:00 2001 From: rigel rozanski Date: Wed, 14 Jun 2017 05:02:42 -0400 Subject: [PATCH 1/9] replace basecli state presenters with cmds --- cmd/basecli/commands/adapters.go | 18 +---------- cmd/basecli/commands/query.go | 55 ++++++++++++++++++++++++++++++++ cmd/basecli/counter/query.go | 44 +++++++++++++++++++++++++ cmd/basecli/main.go | 4 +-- cmd/counter/cmd.go | 16 +++++----- glide.lock | 2 +- 6 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 cmd/basecli/commands/query.go create mode 100644 cmd/basecli/counter/query.go diff --git a/cmd/basecli/commands/adapters.go b/cmd/basecli/commands/adapters.go index 516cb2f0d..7df8ca338 100644 --- a/cmd/basecli/commands/adapters.go +++ b/cmd/basecli/commands/adapters.go @@ -17,22 +17,6 @@ import ( btypes "github.com/tendermint/basecoin/types" ) -type AccountPresenter struct{} - -func (_ AccountPresenter) MakeKey(str string) ([]byte, error) { - res, err := hex.DecodeString(str) - if err == nil { - res = btypes.AccountKey(res) - } - return res, err -} - -func (_ AccountPresenter) ParseData(raw []byte) (interface{}, error) { - var acc *btypes.Account - err := wire.ReadBinaryBytes(raw, &acc) - return acc, err -} - type BaseTxPresenter struct { proofs.RawPresenter // this handles MakeKey as hex bytes } @@ -65,7 +49,7 @@ func (m SendTxMaker) Flags() (*flag.FlagSet, interface{}) { fs.String("to", "", "Destination address for the bits") fs.String("amount", "", "Coins to send in the format ,...") - fs.String("fee", "", "Coins for the transaction fee of the format ") + fs.String("fee", "0mycoin", "Coins for the transaction fee of the format ") fs.Int64("gas", 0, "Amount of gas for this transaction") fs.Int("sequence", -1, "Sequence number for this transaction") return fs, &SendFlags{} diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go new file mode 100644 index 000000000..1162d2b09 --- /dev/null +++ b/cmd/basecli/commands/query.go @@ -0,0 +1,55 @@ +package commands + +import ( + "encoding/hex" + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + + wire "github.com/tendermint/go-wire" + "github.com/tendermint/light-client/commands" + proofcmd "github.com/tendermint/light-client/commands/proofs" + "github.com/tendermint/light-client/proofs" + + bccmd "github.com/tendermint/basecoin/cmd/commands" + btypes "github.com/tendermint/basecoin/types" +) + +func init() { + //first modify the full node account query command for the light client + bccmd.AccountCmd.RunE = accountCmd + proofcmd.RootCmd.AddCommand(bccmd.AccountCmd) +} + +func accountCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("account command requires an argument ([address])") //never stack trace + } + + addrHex := StripHex(args[0]) + + // convert destination address to bytes + addr, err := hex.DecodeString(addrHex) + if err != nil { + return errors.Errorf("Account address (%v) is invalid hex: %v\n", addrHex, err) + } + + // get the proof -> this will be used by all prover commands + height := proofcmd.GetHeight() + node := commands.GetNode() + prover := proofs.NewAppProver(node) + key := btypes.AccountKey(addr) + proof, err := proofcmd.GetProof(node, prover, key, height) + if err != nil { + return err + } + + var acc *btypes.Account + err = wire.ReadBinaryBytes(proof.Data(), &acc) + if err != nil { + return err + } + + return proofcmd.OutputProof(&acc, proof.BlockHeight()) +} diff --git a/cmd/basecli/counter/query.go b/cmd/basecli/counter/query.go new file mode 100644 index 000000000..46973791d --- /dev/null +++ b/cmd/basecli/counter/query.go @@ -0,0 +1,44 @@ +package counter + +import ( + "github.com/spf13/cobra" + + wire "github.com/tendermint/go-wire" + "github.com/tendermint/light-client/commands" + proofcmd "github.com/tendermint/light-client/commands/proofs" + "github.com/tendermint/light-client/proofs" + + "github.com/tendermint/basecoin/plugins/counter" +) + +var CounterTxCmd = &cobra.Command{ + Use: "counter", + Short: "query counter state", + RunE: counterTxCmd, +} + +func init() { + //first modify the full node account query command for the light client + proofcmd.RootCmd.AddCommand(CounterTxCmd) +} + +func counterTxCmd(cmd *cobra.Command, args []string) error { + + // get the proof -> this will be used by all prover commands + height := proofcmd.GetHeight() + node := commands.GetNode() + prover := proofs.NewAppProver(node) + key := counter.New().StateKey() + proof, err := proofcmd.GetProof(node, prover, key, height) + if err != nil { + return err + } + + var cp counter.CounterPluginState + err = wire.ReadBinaryBytes(proof.Data(), &cp) + if err != nil { + return err + } + + return proofcmd.OutputProof(cp, proof.BlockHeight()) +} diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 01dc64683..7af9ce4de 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -33,9 +33,9 @@ func main() { commands.AddBasicFlags(BaseCli) //initialize proofs and txs - proofs.StatePresenters.Register("account", bcmd.AccountPresenter{}) + //proofs.StatePresenters.Register("account", bcmd.AccountPresenter{}) proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) - proofs.StatePresenters.Register("counter", bcount.CounterPresenter{}) + //proofs.StatePresenters.Register("counter", bcount.CounterPresenter{}) txs.Register("send", bcmd.SendTxMaker{}) txs.Register("counter", bcount.CounterTxMaker{}) diff --git a/cmd/counter/cmd.go b/cmd/counter/cmd.go index e83430498..a8c543e13 100644 --- a/cmd/counter/cmd.go +++ b/cmd/counter/cmd.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/spf13/cobra" + "github.com/spf13/viper" wire "github.com/tendermint/go-wire" "github.com/tendermint/basecoin/cmd/commands" @@ -19,16 +20,15 @@ var CounterTxCmd = &cobra.Command{ RunE: counterTxCmd, } -//flags -var ( - validFlag bool - countFeeFlag string +const ( + flagValid = "valid" + flagCountFee = "countfee" ) func init() { - CounterTxCmd.Flags().BoolVar(&validFlag, "valid", false, "Set valid field in CounterTx") - CounterTxCmd.Flags().StringVar(&countFeeFlag, "countfee", "", "Coins for the counter fee of the format ") + CounterTxCmd.Flags().Bool(flagValid, false, "Set valid field in CounterTx") + CounterTxCmd.Flags().String(flagCountFee, "", "Coins for the counter fee of the format ") commands.RegisterTxSubcommand(CounterTxCmd) commands.RegisterStartPlugin("counter", func() types.Plugin { return counter.New() }) @@ -36,13 +36,13 @@ func init() { func counterTxCmd(cmd *cobra.Command, args []string) error { - countFee, err := types.ParseCoins(countFeeFlag) + countFee, err := types.ParseCoins(viper.GetString(flagCountFee)) if err != nil { return err } counterTx := counter.CounterTx{ - Valid: validFlag, + Valid: viper.GetBool(flagValid), Fee: countFee, } diff --git a/glide.lock b/glide.lock index 8379e9e6d..e034a7afc 100644 --- a/glide.lock +++ b/glide.lock @@ -127,7 +127,7 @@ imports: - data - data/base58 - name: github.com/tendermint/light-client - version: 424905d3813586ce7e64e18690676250a0595ad4 + version: d993d8a9ba6cb51f05faf6e527016288e38c2853 subpackages: - certifiers - certifiers/client From 863e3725fe5699717fee531e54ef7ee8d06758b0 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 12:11:27 +0200 Subject: [PATCH 2/9] Update deps to latest light-client pr, breaking changes --- glide.lock | 22 +++++++++++----------- glide.yaml | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/glide.lock b/glide.lock index e034a7afc..fa0ca450d 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: b31c6e45072e1015b04b5a201fb5ffcbadb837f21fe4a499f3b7e93229ee1c45 -updated: 2017-06-02T09:22:48.505187474Z +hash: 6eb1119dccf2ab4d0adb870a14cb4408047119be53c8ec4afeaa281bd1d2b457 +updated: 2017-06-15T12:09:30.832243232+02:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -39,9 +39,9 @@ imports: - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/handlers - version: 13d73096a474cac93275c679c7b8a2dc17ddba82 + version: a4043c62cc2329bacda331d33fc908ab11ef0ec3 - name: github.com/gorilla/mux - version: 392c28fe23e1c45ddba891b0320b3b5df220beea + version: bcd8bc72b08df0f70df986b97f95590779502d31 - name: github.com/gorilla/websocket version: a91eba7f97777409bc2c443f5534d41dd20c5720 - name: github.com/hashicorp/hcl @@ -101,7 +101,7 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/abci - version: b86da575718079396af1f7fe3609ea34be6f855d + version: 7f5f48b6b9ec3964de4b07b6c3cd05d7c91aeee5 subpackages: - client - example/dummy @@ -113,7 +113,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-crypto - version: 7dff40942a64cdeefefa9446b2d104750b349f8a + version: 438b16f1f84ef002d7408ecd6fc3a3974cbc9559 subpackages: - cmd - keys @@ -122,12 +122,12 @@ imports: - keys/server/types - keys/storage/filestorage - name: github.com/tendermint/go-wire - version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb + version: 97beaedf0f4dbc035309157c92be3b30cc6e5d74 subpackages: - data - data/base58 - name: github.com/tendermint/light-client - version: d993d8a9ba6cb51f05faf6e527016288e38c2853 + version: c90f1a90b28977431c6291a0162228e9e4250401 subpackages: - certifiers - certifiers/client @@ -139,13 +139,13 @@ imports: - commands/txs - proofs - name: github.com/tendermint/merkleeyes - version: 6b06ad654956c951b3d27e38bb566ae45aae1ff7 + version: c722818b460381bc5b82e38c73ff6e22a9df624d subpackages: - app - client - iavl - name: github.com/tendermint/tendermint - version: 2b5b0172531319ebc255a0ba638f6be666e5e46c + version: 11b5d11e9eec170e1d3dce165f0270d5c0759d69 subpackages: - blockchain - cmd/tendermint/commands @@ -172,7 +172,7 @@ imports: - types - version - name: github.com/tendermint/tmlibs - version: 6b619742ac69388dd591c30f55aaee46197b086e + version: 0ecb38c6da95a1e8f60117b2bd4a6f76c7a0f944 subpackages: - autofile - cli diff --git a/glide.yaml b/glide.yaml index 132e8db24..7e7727aac 100644 --- a/glide.yaml +++ b/glide.yaml @@ -7,22 +7,22 @@ import: - package: github.com/spf13/pflag - package: github.com/spf13/viper - package: github.com/tendermint/abci - version: ~0.5.0 + version: develop version: subpackages: - server - types - package: github.com/tendermint/go-crypto - version: ~0.2.0 + version: develop subpackages: - cmd - keys - package: github.com/tendermint/go-wire - version: ~0.6.2 + version: develop subpackages: - data - package: github.com/tendermint/light-client - version: ~0.10.0 + version: develop subpackages: - commands - commands/proofs @@ -30,12 +30,12 @@ import: - commands/txs - proofs - package: github.com/tendermint/merkleeyes - version: ~0.2.0 + version: develop subpackages: - client - iavl - package: github.com/tendermint/tendermint - version: ~0.10.0 + version: develop subpackages: - config - node @@ -46,7 +46,7 @@ import: - rpc/lib/types - types - package: github.com/tendermint/tmlibs - version: ~0.2.0 + version: develop subpackages: - cli - cli/flags From 65837cf9525ce630941b1c037f2dafe4c996dd3c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 12:27:55 +0200 Subject: [PATCH 3/9] Clean up queries, part 1 --- cmd/basecli/commands/query.go | 34 +++++++++++----------------------- cmd/basecli/counter/query.go | 18 ++++++------------ cmd/basecli/main.go | 25 ++++++++++++++++++------- 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go index 1162d2b09..84098a424 100644 --- a/cmd/basecli/commands/query.go +++ b/cmd/basecli/commands/query.go @@ -1,10 +1,6 @@ package commands import ( - "encoding/hex" - "fmt" - - "github.com/pkg/errors" "github.com/spf13/cobra" wire "github.com/tendermint/go-wire" @@ -12,44 +8,36 @@ import ( proofcmd "github.com/tendermint/light-client/commands/proofs" "github.com/tendermint/light-client/proofs" - bccmd "github.com/tendermint/basecoin/cmd/commands" btypes "github.com/tendermint/basecoin/types" ) -func init() { - //first modify the full node account query command for the light client - bccmd.AccountCmd.RunE = accountCmd - proofcmd.RootCmd.AddCommand(bccmd.AccountCmd) +var AccountQueryCmd = &cobra.Command{ + Use: "account [address]", + Short: "Get details of an account, with proof", + RunE: doAccountQuery, } -func accountCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("account command requires an argument ([address])") //never stack trace - } - - addrHex := StripHex(args[0]) - - // convert destination address to bytes - addr, err := hex.DecodeString(addrHex) +func doAccountQuery(cmd *cobra.Command, args []string) error { + height := proofcmd.GetHeight() + addr, err := proofcmd.ParseHexKey(args, "address") if err != nil { - return errors.Errorf("Account address (%v) is invalid hex: %v\n", addrHex, err) + return err } + key := btypes.AccountKey(addr) // get the proof -> this will be used by all prover commands - height := proofcmd.GetHeight() node := commands.GetNode() prover := proofs.NewAppProver(node) - key := btypes.AccountKey(addr) proof, err := proofcmd.GetProof(node, prover, key, height) if err != nil { return err } - var acc *btypes.Account + acc := new(btypes.Account) err = wire.ReadBinaryBytes(proof.Data(), &acc) if err != nil { return err } - return proofcmd.OutputProof(&acc, proof.BlockHeight()) + return proofcmd.OutputProof(acc, proof.BlockHeight()) } diff --git a/cmd/basecli/counter/query.go b/cmd/basecli/counter/query.go index 46973791d..bb18eee69 100644 --- a/cmd/basecli/counter/query.go +++ b/cmd/basecli/counter/query.go @@ -11,24 +11,18 @@ import ( "github.com/tendermint/basecoin/plugins/counter" ) -var CounterTxCmd = &cobra.Command{ +var CounterQueryCmd = &cobra.Command{ Use: "counter", - Short: "query counter state", - RunE: counterTxCmd, + Short: "Query counter state, with proof", + RunE: doCounterQuery, } -func init() { - //first modify the full node account query command for the light client - proofcmd.RootCmd.AddCommand(CounterTxCmd) -} - -func counterTxCmd(cmd *cobra.Command, args []string) error { - - // get the proof -> this will be used by all prover commands +func doCounterQuery(cmd *cobra.Command, args []string) error { height := proofcmd.GetHeight() + key := counter.New().StateKey() + node := commands.GetNode() prover := proofs.NewAppProver(node) - key := counter.New().StateKey() proof, err := proofcmd.GetProof(node, prover, key, height) if err != nil { return err diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 7af9ce4de..964e0d944 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -32,8 +32,19 @@ tmcli to work for any custom abci app. func main() { commands.AddBasicFlags(BaseCli) - //initialize proofs and txs - //proofs.StatePresenters.Register("account", bcmd.AccountPresenter{}) + // prepare queries + pr := proofs.RootCmd + // these are default parsers, but you optional in your app + pr.AddCommand(proofs.TxCmd) + pr.AddCommand(proofs.KeyCmd) + pr.AddCommand(bcmd.AccountQueryCmd) + pr.AddCommand(bcount.CounterQueryCmd) + + // here is how you would add the custom txs... but don't really add demo in your app + tr := txs.RootCmd + // tr.AddCommand(txs.DemoCmd) + + // TODO proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) //proofs.StatePresenters.Register("counter", bcount.CounterPresenter{}) @@ -42,13 +53,13 @@ func main() { // set up the various commands to use BaseCli.AddCommand( - keycmd.RootCmd, commands.InitCmd, + commands.ResetCmd, + keycmd.RootCmd, seeds.RootCmd, - proofs.RootCmd, - txs.RootCmd, - proxy.RootCmd, - ) + pr, + tr, + proxy.RootCmd) cmd := cli.PrepareMainCmd(BaseCli, "BC", os.ExpandEnv("$HOME/.basecli")) cmd.Execute() From 66ec2f266cf89f4cf336aa7baad58f6b330eb59e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 13:11:09 +0200 Subject: [PATCH 4/9] Port sendtx to new format --- cmd/basecli/commands/adapters.go | 152 +++++++++++++------------------ cmd/basecli/commands/query.go | 12 +++ cmd/basecli/commands/sendtx.go | 52 +++++++++++ cmd/basecli/counter/counter.go | 13 --- cmd/basecli/counter/query.go | 15 +++ cmd/basecli/main.go | 13 ++- glide.lock | 2 +- 7 files changed, 151 insertions(+), 108 deletions(-) diff --git a/cmd/basecli/commands/adapters.go b/cmd/basecli/commands/adapters.go index 7df8ca338..f9bfe0f44 100644 --- a/cmd/basecli/commands/adapters.go +++ b/cmd/basecli/commands/adapters.go @@ -2,126 +2,104 @@ package commands import ( "encoding/hex" - "encoding/json" "github.com/pkg/errors" + "github.com/spf13/cobra" flag "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" - lightclient "github.com/tendermint/light-client" "github.com/tendermint/light-client/commands" - "github.com/tendermint/light-client/proofs" + txcmd "github.com/tendermint/light-client/commands/txs" btypes "github.com/tendermint/basecoin/types" ) -type BaseTxPresenter struct { - proofs.RawPresenter // this handles MakeKey as hex bytes +/*** Here is the sendtx command ***/ + +var SendTxCmd = &cobra.Command{ + Use: "send", + Short: "send tokens from one account to another", + RunE: doSendTx, } -func (_ BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { - var tx btypes.TxS - err := wire.ReadBinaryBytes(raw, &tx) - return tx, err +const ( + ToFlag = "to" + AmountFlag = "amount" + FeeFlag = "fee" + GasFlag = "gas" + SequenceFlag = "sequence" +) + +func init() { + flags := SendTxCmd.Flags() + flags.String(ToFlag, "", "Destination address for the bits") + flags.String(AmountFlag, "", "Coins to send in the format ,...") + flags.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format ") + flags.Int64(GasFlag, 0, "Amount of gas for this transaction") + flags.Int(SequenceFlag, -1, "Sequence number for this transaction") } -/******** SendTx *********/ +// runDemo is an example of how to make a tx +func doSendTx(cmd *cobra.Command, args []string) error { + tx := new(btypes.SendTx) -type SendTxMaker struct{} - -func (m SendTxMaker) MakeReader() (lightclient.TxReader, error) { - chainID := viper.GetString(commands.ChainFlag) - return SendTxReader{ChainID: chainID}, nil -} - -type SendFlags struct { - To string - Amount string - Fee string - Gas int64 - Sequence int -} - -func (m SendTxMaker) Flags() (*flag.FlagSet, interface{}) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - - fs.String("to", "", "Destination address for the bits") - fs.String("amount", "", "Coins to send in the format ,...") - fs.String("fee", "0mycoin", "Coins for the transaction fee of the format ") - fs.Int64("gas", 0, "Amount of gas for this transaction") - fs.Int("sequence", -1, "Sequence number for this transaction") - return fs, &SendFlags{} -} - -// SendTXReader allows us to create SendTx -type SendTxReader struct { - ChainID string -} - -func (t SendTxReader) ReadTxJSON(data []byte, pk crypto.PubKey) (interface{}, error) { - // TODO: use pk info to help construct data - var tx btypes.SendTx - err := json.Unmarshal(data, &tx) - send := SendTx{ - chainID: t.ChainID, - Tx: &tx, + // load data from json or flags + found, err := txcmd.LoadJSON(tx) + if !found { + err = readSendTxFlags(tx) } - return &send, errors.Wrap(err, "parse sendtx") + if err != nil { + return err + } + + send := &SendTx{ + chainID: viper.GetString(commands.ChainFlag), + Tx: tx, + } + send.AddSigner(txcmd.GetSigner()) + + // Sign if needed and post. This it the work-horse + bres, err := txcmd.SignAndPostTx(send) + if err != nil { + return err + } + + // output result + return txcmd.OutputTx(bres) } -func (t SendTxReader) ReadTxFlags(flags interface{}, pk crypto.PubKey) (interface{}, error) { - data := flags.(*SendFlags) - - // parse to and from addresses - to, err := hex.DecodeString(StripHex(data.To)) +func readSendTxFlags(tx *btypes.SendTx) error { + // parse to address + to, err := hex.DecodeString(StripHex(viper.GetString(ToFlag))) if err != nil { - return nil, errors.Errorf("To address is invalid hex: %v\n", err) + return errors.Errorf("To address is invalid hex: %v\n", err) } //parse the fee and amounts into coin types - feeCoin, err := btypes.ParseCoin(data.Fee) + tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag)) if err != nil { - return nil, err + return err } - amountCoins, err := btypes.ParseCoins(data.Amount) + amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag)) if err != nil { - return nil, err + return err } - // get addr if available - var addr []byte - if !pk.Empty() { - addr = pk.Address() - } + // set the gas + tx.Gas = viper.GetInt64(GasFlag) - // craft the tx - input := btypes.TxInput{ - Address: addr, + // craft the inputs and outputs + tx.Inputs = []btypes.TxInput{{ Coins: amountCoins, - Sequence: data.Sequence, - } - if data.Sequence == 1 { - input.PubKey = pk - } - output := btypes.TxOutput{ + Sequence: viper.GetInt(SequenceFlag), + }} + tx.Outputs = []btypes.TxOutput{{ Address: to, Coins: amountCoins, - } - tx := btypes.SendTx{ - Gas: data.Gas, - Fee: feeCoin, - Inputs: []btypes.TxInput{input}, - Outputs: []btypes.TxOutput{output}, - } + }} - // wrap it in the proper signer thing... - send := SendTx{ - chainID: t.ChainID, - Tx: &tx, - } - return &send, nil + return nil } /******** AppTx *********/ diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go index 84098a424..aea350d06 100644 --- a/cmd/basecli/commands/query.go +++ b/cmd/basecli/commands/query.go @@ -41,3 +41,15 @@ func doAccountQuery(cmd *cobra.Command, args []string) error { return proofcmd.OutputProof(acc, proof.BlockHeight()) } + +/*** this decodes the basecoin tx ***/ + +type BaseTxPresenter struct { + proofs.RawPresenter // this handles MakeKey as hex bytes +} + +func (_ BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { + var tx btypes.TxS + err := wire.ReadBinaryBytes(raw, &tx) + return tx, err +} diff --git a/cmd/basecli/commands/sendtx.go b/cmd/basecli/commands/sendtx.go index 0660ed22c..ccf00c6ed 100644 --- a/cmd/basecli/commands/sendtx.go +++ b/cmd/basecli/commands/sendtx.go @@ -58,3 +58,55 @@ func (s *SendTx) TxBytes() ([]byte, error) { }{s.Tx}) return txBytes, nil } + +// AddSigner sets address and pubkey info on the tx based on the key that +// will be used for signing +func (s *SendTx) AddSigner(pk crypto.PubKey) { + // get addr if available + var addr []byte + if !pk.Empty() { + addr = pk.Address() + } + + // set the send address, and pubkey if needed + in := s.Tx.Inputs + in[0].Address = addr + if in[0].Sequence == 1 { + in[0].PubKey = pk + } +} + +// TODO: this should really be in the basecoin.types SendTx, +// but that code is too ugly now, needs refactor.. +func (s *SendTx) ValidateBasic() error { + if s.chainID == "" { + return errors.New("No chainId specified") + } + for _, in := range s.Tx.Inputs { + if len(in.Address) != 20 { + return errors.Errorf("Invalid input address length: %d", len(in.Address)) + } + if !in.Coins.IsValid() { + return errors.Errorf("Invalid input coins %v", in.Coins) + } + if in.Coins.IsZero() { + return errors.New("Input coins cannot be zero") + } + if in.Sequence <= 0 { + return errors.New("Sequence must be greater than 0") + } + } + for _, out := range s.Tx.Outputs { + if len(out.Address) != 20 { + return errors.Errorf("Invalid output address length: %d", len(out.Address)) + } + if !out.Coins.IsValid() { + return errors.Errorf("Invalid output coins %v", out.Coins) + } + if out.Coins.IsZero() { + return errors.New("Output coins cannot be zero") + } + } + + return nil +} diff --git a/cmd/basecli/counter/counter.go b/cmd/basecli/counter/counter.go index 3576e1629..9ec931091 100644 --- a/cmd/basecli/counter/counter.go +++ b/cmd/basecli/counter/counter.go @@ -15,19 +15,6 @@ import ( btypes "github.com/tendermint/basecoin/types" ) -type CounterPresenter struct{} - -func (_ CounterPresenter) MakeKey(str string) ([]byte, error) { - key := counter.New().StateKey() - return key, nil -} - -func (_ CounterPresenter) ParseData(raw []byte) (interface{}, error) { - var cp counter.CounterPluginState - err := wire.ReadBinaryBytes(raw, &cp) - return cp, err -} - /**** build out the tx ****/ var ( diff --git a/cmd/basecli/counter/query.go b/cmd/basecli/counter/query.go index bb18eee69..9396c956a 100644 --- a/cmd/basecli/counter/query.go +++ b/cmd/basecli/counter/query.go @@ -36,3 +36,18 @@ func doCounterQuery(cmd *cobra.Command, args []string) error { return proofcmd.OutputProof(cp, proof.BlockHeight()) } + +/*** doesn't seem to be needed anymore??? ***/ + +// type CounterPresenter struct{} + +// func (_ CounterPresenter) MakeKey(str string) ([]byte, error) { +// key := counter.New().StateKey() +// return key, nil +// } + +// func (_ CounterPresenter) ParseData(raw []byte) (interface{}, error) { +// var cp counter.CounterPluginState +// err := wire.ReadBinaryBytes(raw, &cp) +// return cp, err +// } diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 964e0d944..9b58d1204 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -14,7 +14,6 @@ import ( "github.com/tendermint/tmlibs/cli" bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" - bcount "github.com/tendermint/basecoin/cmd/basecli/counter" ) // BaseCli represents the base command when called without any subcommands @@ -38,18 +37,18 @@ func main() { pr.AddCommand(proofs.TxCmd) pr.AddCommand(proofs.KeyCmd) pr.AddCommand(bcmd.AccountQueryCmd) - pr.AddCommand(bcount.CounterQueryCmd) + // pr.AddCommand(bcount.CounterQueryCmd) // here is how you would add the custom txs... but don't really add demo in your app + proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) tr := txs.RootCmd - // tr.AddCommand(txs.DemoCmd) + tr.AddCommand(bcmd.SendTxCmd) + // tr.AddCommand(bcmd.AppTxCmd) // TODO - proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) - //proofs.StatePresenters.Register("counter", bcount.CounterPresenter{}) - txs.Register("send", bcmd.SendTxMaker{}) - txs.Register("counter", bcount.CounterTxMaker{}) + // txs.Register("send", bcmd.SendTxMaker{}) + // txs.Register("counter", bcount.CounterTxMaker{}) // set up the various commands to use BaseCli.AddCommand( diff --git a/glide.lock b/glide.lock index fa0ca450d..8964951f0 100644 --- a/glide.lock +++ b/glide.lock @@ -172,7 +172,7 @@ imports: - types - version - name: github.com/tendermint/tmlibs - version: 0ecb38c6da95a1e8f60117b2bd4a6f76c7a0f944 + version: 59a77e7bef092eef0e1f9b44c983dc9e35eed0d6 subpackages: - autofile - cli From 8f67b6be84e7a5309c66ffbfe1bda737ff69b0fe Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 13:36:18 +0200 Subject: [PATCH 5/9] Got counter tx working, needs testing --- cmd/basecli/commands/apptx.go | 39 ++++++++ cmd/basecli/commands/{adapters.go => cmds.go} | 85 ++++++---------- cmd/basecli/counter/counter.go | 99 ++++++++++--------- cmd/basecli/main.go | 5 +- 4 files changed, 125 insertions(+), 103 deletions(-) rename cmd/basecli/commands/{adapters.go => cmds.go} (64%) diff --git a/cmd/basecli/commands/apptx.go b/cmd/basecli/commands/apptx.go index 7cf9e3c6a..1e68600e1 100644 --- a/cmd/basecli/commands/apptx.go +++ b/cmd/basecli/commands/apptx.go @@ -57,3 +57,42 @@ func (s *AppTx) TxBytes() ([]byte, error) { txBytes := wire.BinaryBytes(bc.TxS{s.Tx}) return txBytes, nil } + +// AddSigner sets address and pubkey info on the tx based on the key that +// will be used for signing +func (a *AppTx) AddSigner(pk crypto.PubKey) { + // get addr if available + var addr []byte + if !pk.Empty() { + addr = pk.Address() + } + + // set the send address, and pubkey if needed + in := &a.Tx.Input + in.Address = addr + if in.Sequence == 1 { + in.PubKey = pk + } +} + +// TODO: this should really be in the basecoin.types SendTx, +// but that code is too ugly now, needs refactor.. +func (a *AppTx) ValidateBasic() error { + if a.chainID == "" { + return errors.New("No chainId specified") + } + in := a.Tx.Input + if len(in.Address) != 20 { + return errors.Errorf("Invalid input address length: %d", len(in.Address)) + } + if !in.Coins.IsValid() { + return errors.Errorf("Invalid input coins %v", in.Coins) + } + if in.Coins.IsZero() { + return errors.New("Input coins cannot be zero") + } + if in.Sequence <= 0 { + return errors.New("Sequence must be greater than 0") + } + return nil +} diff --git a/cmd/basecli/commands/adapters.go b/cmd/basecli/commands/cmds.go similarity index 64% rename from cmd/basecli/commands/adapters.go rename to cmd/basecli/commands/cmds.go index f9bfe0f44..268f4d61d 100644 --- a/cmd/basecli/commands/adapters.go +++ b/cmd/basecli/commands/cmds.go @@ -8,7 +8,6 @@ import ( flag "github.com/spf13/pflag" "github.com/spf13/viper" - crypto "github.com/tendermint/go-crypto" "github.com/tendermint/light-client/commands" txcmd "github.com/tendermint/light-client/commands/txs" @@ -71,7 +70,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { func readSendTxFlags(tx *btypes.SendTx) error { // parse to address - to, err := hex.DecodeString(StripHex(viper.GetString(ToFlag))) + to, err := ParseHexFlag(ToFlag) if err != nil { return errors.Errorf("To address is invalid hex: %v\n", err) } @@ -104,76 +103,52 @@ func readSendTxFlags(tx *btypes.SendTx) error { /******** AppTx *********/ -type AppFlags struct { - Fee string - Gas int64 - Amount string - Sequence int +func AddAppTxFlags(fs *flag.FlagSet) { + fs.String(AmountFlag, "", "Coins to send in the format ,...") + fs.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format ") + fs.Int64(GasFlag, 0, "Amount of gas for this transaction") + fs.Int(SequenceFlag, -1, "Sequence number for this transaction") } -func AppFlagSet() (*flag.FlagSet, AppFlags) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - - fs.String("amount", "", "Coins to send in the format ,...") - fs.String("fee", "", "Coins for the transaction fee of the format ") - fs.Int64("gas", 0, "Amount of gas for this transaction") - fs.Int("sequence", -1, "Sequence number for this transaction") - return fs, AppFlags{} -} - -// AppTxReader allows us to create AppTx -type AppTxReader struct { - ChainID string -} - -func (t AppTxReader) ReadTxJSON(data []byte, pk crypto.PubKey) (interface{}, error) { - return nil, errors.New("Not implemented...") -} - -func (t AppTxReader) ReadTxFlags(data *AppFlags, app string, appData []byte, pk crypto.PubKey) (interface{}, error) { +// ReadAppTxFlags reads in the standard flags +// your command should parse info to set tx.Name and tx.Data +func ReadAppTxFlags(tx *btypes.AppTx) error { //parse the fee and amounts into coin types - feeCoin, err := btypes.ParseCoin(data.Fee) + var err error + tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag)) if err != nil { - return nil, err + return err } - amountCoins, err := btypes.ParseCoins(data.Amount) + amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag)) if err != nil { - return nil, err + return err } - // get addr if available - var addr []byte - if !pk.Empty() { - addr = pk.Address() - } + // set the gas + tx.Gas = viper.GetInt64(GasFlag) - // craft the tx - input := btypes.TxInput{ - Address: addr, + // craft the inputs and outputs + tx.Input = btypes.TxInput{ Coins: amountCoins, - Sequence: data.Sequence, - } - if data.Sequence == 1 { - input.PubKey = pk - } - tx := btypes.AppTx{ - Gas: data.Gas, - Fee: feeCoin, - Input: input, - Name: app, - Data: appData, + Sequence: viper.GetInt(SequenceFlag), } - // wrap it in the proper signer thing... - send := AppTx{ - chainID: t.ChainID, - Tx: &tx, + return nil +} + +func WrapAppTx(tx *btypes.AppTx) *AppTx { + return &AppTx{ + chainID: viper.GetString(commands.ChainFlag), + Tx: tx, } - return &send, nil } /** TODO copied from basecoin cli - put in common somewhere? **/ +func ParseHexFlag(flag string) ([]byte, error) { + return hex.DecodeString(StripHex(viper.GetString(flag))) +} + // Returns true for non-empty hex-string prefixed with "0x" func isHex(s string) bool { if len(s) > 2 && s[:2] == "0x" { diff --git a/cmd/basecli/counter/counter.go b/cmd/basecli/counter/counter.go index 9ec931091..b39792e2c 100644 --- a/cmd/basecli/counter/counter.go +++ b/cmd/basecli/counter/counter.go @@ -1,72 +1,79 @@ package counter import ( - flag "github.com/spf13/pflag" + "github.com/spf13/cobra" "github.com/spf13/viper" - crypto "github.com/tendermint/go-crypto" wire "github.com/tendermint/go-wire" - lightclient "github.com/tendermint/light-client" - "github.com/tendermint/light-client/commands" - "github.com/tendermint/light-client/commands/txs" + txcmd "github.com/tendermint/light-client/commands/txs" bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" "github.com/tendermint/basecoin/plugins/counter" btypes "github.com/tendermint/basecoin/types" ) -/**** build out the tx ****/ +var CounterTxCmd = &cobra.Command{ + Use: "counter", + Short: "add a vote to the counter", + Long: `Add a vote to the counter. -var ( - _ txs.ReaderMaker = CounterTxMaker{} - _ lightclient.TxReader = CounterTxReader{} +You must pass --valid for it to count and the countfee will be added to the counter.`, + RunE: doCounterTx, +} + +const ( + CountFeeFlag = "countfee" + ValidFlag = "valid" ) -type CounterTxMaker struct{} - -func (m CounterTxMaker) MakeReader() (lightclient.TxReader, error) { - chainID := viper.GetString(commands.ChainFlag) - return CounterTxReader{bcmd.AppTxReader{ChainID: chainID}}, nil +func init() { + fs := CounterTxCmd.Flags() + bcmd.AddAppTxFlags(fs) + fs.String(CountFeeFlag, "", "Coins to send in the format ,...") + fs.Bool(ValidFlag, false, "Is count valid?") } -// define flags +func doCounterTx(cmd *cobra.Command, args []string) error { + tx := new(btypes.AppTx) + // Note: we don't support loading apptx from json currently, so skip that -type CounterFlags struct { - bcmd.AppFlags `mapstructure:",squash"` - Valid bool - CountFee string -} - -func (m CounterTxMaker) Flags() (*flag.FlagSet, interface{}) { - fs, app := bcmd.AppFlagSet() - fs.String("countfee", "", "Coins to send in the format ,...") - fs.Bool("valid", false, "Is count valid?") - return fs, &CounterFlags{AppFlags: app} -} - -// parse flags - -type CounterTxReader struct { - App bcmd.AppTxReader -} - -func (t CounterTxReader) ReadTxJSON(data []byte, pk crypto.PubKey) (interface{}, error) { - // TODO: something. maybe? - return t.App.ReadTxJSON(data, pk) -} - -func (t CounterTxReader) ReadTxFlags(flags interface{}, pk crypto.PubKey) (interface{}, error) { - data := flags.(*CounterFlags) - countFee, err := btypes.ParseCoins(data.CountFee) + // read the standard flags + err := bcmd.ReadAppTxFlags(tx) if err != nil { - return nil, err + return err } + // now read the app-specific flags + err = readCounterFlags(tx) + if err != nil { + return err + } + + app := bcmd.WrapAppTx(tx) + app.AddSigner(txcmd.GetSigner()) + + // Sign if needed and post. This it the work-horse + bres, err := txcmd.SignAndPostTx(app) + if err != nil { + return err + } + + // output result + return txcmd.OutputTx(bres) +} + +// readCounterFlags sets the app-specific data in the AppTx +func readCounterFlags(tx *btypes.AppTx) error { + countFee, err := btypes.ParseCoins(viper.GetString(CountFeeFlag)) + if err != nil { + return err + } ctx := counter.CounterTx{ - Valid: viper.GetBool("valid"), + Valid: viper.GetBool(ValidFlag), Fee: countFee, } - txBytes := wire.BinaryBytes(ctx) - return t.App.ReadTxFlags(&data.AppFlags, counter.New().Name(), txBytes, pk) + tx.Name = counter.New().Name() + tx.Data = wire.BinaryBytes(ctx) + return nil } diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 9b58d1204..d5116d160 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tmlibs/cli" bcmd "github.com/tendermint/basecoin/cmd/basecli/commands" + bcount "github.com/tendermint/basecoin/cmd/basecli/counter" ) // BaseCli represents the base command when called without any subcommands @@ -37,13 +38,13 @@ func main() { pr.AddCommand(proofs.TxCmd) pr.AddCommand(proofs.KeyCmd) pr.AddCommand(bcmd.AccountQueryCmd) - // pr.AddCommand(bcount.CounterQueryCmd) + pr.AddCommand(bcount.CounterQueryCmd) // here is how you would add the custom txs... but don't really add demo in your app proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) tr := txs.RootCmd tr.AddCommand(bcmd.SendTxCmd) - // tr.AddCommand(bcmd.AppTxCmd) + tr.AddCommand(bcount.CounterTxCmd) // TODO From 282a1579976718a63ba6424f657136d7f861836f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 15:59:45 +0200 Subject: [PATCH 6/9] Update to use new helper methods, less code dups --- cmd/basecli/commands/cmds.go | 4 ++-- cmd/basecli/commands/query.go | 14 ++------------ cmd/basecli/counter/query.go | 13 +------------ glide.lock | 2 +- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go index 268f4d61d..50a39024b 100644 --- a/cmd/basecli/commands/cmds.go +++ b/cmd/basecli/commands/cmds.go @@ -53,7 +53,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { } send := &SendTx{ - chainID: viper.GetString(commands.ChainFlag), + chainID: commands.GetChainID(), Tx: tx, } send.AddSigner(txcmd.GetSigner()) @@ -138,7 +138,7 @@ func ReadAppTxFlags(tx *btypes.AppTx) error { func WrapAppTx(tx *btypes.AppTx) *AppTx { return &AppTx{ - chainID: viper.GetString(commands.ChainFlag), + chainID: commands.GetChainID(), Tx: tx, } } diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go index aea350d06..82ec56491 100644 --- a/cmd/basecli/commands/query.go +++ b/cmd/basecli/commands/query.go @@ -4,7 +4,6 @@ import ( "github.com/spf13/cobra" wire "github.com/tendermint/go-wire" - "github.com/tendermint/light-client/commands" proofcmd "github.com/tendermint/light-client/commands/proofs" "github.com/tendermint/light-client/proofs" @@ -18,23 +17,14 @@ var AccountQueryCmd = &cobra.Command{ } func doAccountQuery(cmd *cobra.Command, args []string) error { - height := proofcmd.GetHeight() addr, err := proofcmd.ParseHexKey(args, "address") if err != nil { return err } key := btypes.AccountKey(addr) - // get the proof -> this will be used by all prover commands - node := commands.GetNode() - prover := proofs.NewAppProver(node) - proof, err := proofcmd.GetProof(node, prover, key, height) - if err != nil { - return err - } - acc := new(btypes.Account) - err = wire.ReadBinaryBytes(proof.Data(), &acc) + proof, err := proofcmd.GetAndParseAppProof(key, &acc) if err != nil { return err } @@ -42,7 +32,7 @@ func doAccountQuery(cmd *cobra.Command, args []string) error { return proofcmd.OutputProof(acc, proof.BlockHeight()) } -/*** this decodes the basecoin tx ***/ +/*** this decodes all basecoin tx ***/ type BaseTxPresenter struct { proofs.RawPresenter // this handles MakeKey as hex bytes diff --git a/cmd/basecli/counter/query.go b/cmd/basecli/counter/query.go index 9396c956a..a1c6aeb9b 100644 --- a/cmd/basecli/counter/query.go +++ b/cmd/basecli/counter/query.go @@ -3,10 +3,7 @@ package counter import ( "github.com/spf13/cobra" - wire "github.com/tendermint/go-wire" - "github.com/tendermint/light-client/commands" proofcmd "github.com/tendermint/light-client/commands/proofs" - "github.com/tendermint/light-client/proofs" "github.com/tendermint/basecoin/plugins/counter" ) @@ -18,18 +15,10 @@ var CounterQueryCmd = &cobra.Command{ } func doCounterQuery(cmd *cobra.Command, args []string) error { - height := proofcmd.GetHeight() key := counter.New().StateKey() - node := commands.GetNode() - prover := proofs.NewAppProver(node) - proof, err := proofcmd.GetProof(node, prover, key, height) - if err != nil { - return err - } - var cp counter.CounterPluginState - err = wire.ReadBinaryBytes(proof.Data(), &cp) + proof, err := proofcmd.GetAndParseAppProof(key, &cp) if err != nil { return err } diff --git a/glide.lock b/glide.lock index 8964951f0..bd3888209 100644 --- a/glide.lock +++ b/glide.lock @@ -127,7 +127,7 @@ imports: - data - data/base58 - name: github.com/tendermint/light-client - version: c90f1a90b28977431c6291a0162228e9e4250401 + version: 88fb726e779d97acac5f0bd387892bfc541f3701 subpackages: - certifiers - certifiers/client From 66c9010bcbc46ca5420481edf424062350446bc6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 17:16:00 +0200 Subject: [PATCH 7/9] Starting bash cli tests --- .gitignore | 1 + Makefile | 18 +++++--- clitest/basictx.sh | 107 +++++++++++++++++++++++++++++++++++++++++++++ clitest/ibc.sh | 3 ++ 4 files changed, 124 insertions(+), 5 deletions(-) create mode 100755 clitest/basictx.sh create mode 100755 clitest/ibc.sh diff --git a/.gitignore b/.gitignore index f906ef0e4..cc8fd5d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor merkleeyes.db build +shunit2 diff --git a/Makefile b/Makefile index 96897b250..3cb3937e7 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GOTOOLS = \ github.com/Masterminds/glide PACKAGES=$(shell go list ./... | grep -v '/vendor/') -all: test install +all: get_vendor_deps test install build: go build ./cmd/... @@ -15,15 +15,23 @@ dist: @bash scripts/dist.sh @bash scripts/publish.sh +clitest/shunit2: + wget "https://raw.githubusercontent.com/kward/shunit2/master/source/2.1/src/shunit2" \ + -q -O clitest/shunit2 + +test_cli: clitest/shunit2 + @./clitest/basictx.sh + # @./clitest/ibc.sh + test: go test $(PACKAGES) #go run tests/tendermint/*.go -get_deps: - go get -d ./... +# get_deps: +# go get -d ./... -update_deps: - go get -d -u ./... +# update_deps: +# go get -d -u ./... get_vendor_deps: tools glide install diff --git a/clitest/basictx.sh b/clitest/basictx.sh new file mode 100755 index 000000000..0cface81f --- /dev/null +++ b/clitest/basictx.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +oneTimeSetUp() { + BASE_DIR=$HOME/.basecoin_test_basictx + LOG=$BASE_DIR/test.log + SERVER_LOG=$BASE_DIR/basecoin.log + + rm -rf $BASE_DIR + mkdir -p $BASE_DIR + + ACCOUNTS=(jae ethan bucky rigel igor) + RICH=${ACCOUNTS[0]} + POOR=${ACCOUNTS[1]} + + # set up client + prepareClient + + # start basecoin server (with counter) + initServer + sleep 5 + PID_SERVER=$! + echo pid $PID_SERVER + + initClient + + echo "...Testing may begin!" + echo + echo + echo +} + +oneTimeTearDown() { + echo "stopping basecoin test server" + kill -9 $PID_SERVER + sleep 1 +} + +prepareClient() { + echo "Preparing client keys..." + export BC_HOME=$BASE_DIR/client + basecli reset_all + assertTrue $? + + for i in "${!ACCOUNTS[@]}"; do + newKey ${ACCOUNTS[$i]} + done +} + +initServer() { + echo "Setting up genesis..." + SERVE_DIR=$BASE_DIR/server + rm -rf $SERVE_DIR 2>/dev/null + basecoin init --home=$SERVE_DIR >>$SERVER_LOG + + #change the genesis to the first account + GENKEY=$(basecli keys get ${RICH} -o json | jq .pubkey.data) + GENJSON=$(cat $SERVE_DIR/genesis.json) + echo $GENJSON | jq '.app_options.accounts[0].pub_key.data='$GENKEY > $SERVE_DIR/genesis.json + + echo "Starting server..." + basecoin start --home=$SERVE_DIR >>$SERVER_LOG 2>&1 & +} + +initClient() { + echo "Attaching client..." + # hard-code the expected validator hash + basecli init --chainid=test_chain_id --node=tcp://localhost:46657 --valhash=EB168E17E45BAEB194D4C79067FFECF345C64DE6 + assertTrue "initialized light-client" $? +} + +# newKeys makes a key for a given username, second arg optional password +newKey(){ + assertNotNull "keyname required" "$1" + KEYPASS=${2:-qwertyuiop} + (echo $KEYPASS; echo $KEYPASS) | basecli keys new $1 >>$LOG 2>/dev/null + assertTrue "created $1" $? + assertTrue "$1 doesn't exist" "basecli keys get $1" +} + +# getAddr gets the address for a key name +getAddr() { + assertNotNull "keyname required" "$1" + RAW=$(basecli keys get $1) + assertTrue "no key for $1" $? + # print the addr + echo $RAW | cut -d' ' -f2 +} + +testGetAccount() { + SENDER=$(getAddr $RICH) + RECV=$(getAddr $POOR) + + echo sender $RICH + echo $SENDER + + echo recipient $POOR + echo $RECV + + assertFalse "requires arg" "basecli query account" + ACCT=$(basecli query account $SENDER) + assertTrue "must have proper genesis account" $? + echo $ACCT +} + +# load and run these tests with shunit2! +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory +. $DIR/shunit2 diff --git a/clitest/ibc.sh b/clitest/ibc.sh new file mode 100755 index 000000000..2b0c889a7 --- /dev/null +++ b/clitest/ibc.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "ibc test not implemented" From cfe13e9c130ea5e29f291cf4b8e15b3cfeaca539 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 17:45:44 +0200 Subject: [PATCH 8/9] Cleanup proof format, complete basic cli tests --- Makefile | 1 + clitest/basictx.sh | 60 ++++++++++++++++++++++++++++++++++++---------- glide.lock | 2 +- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 3cb3937e7..c336e05e2 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ clitest/shunit2: -q -O clitest/shunit2 test_cli: clitest/shunit2 + # sudo apt-get install jq @./clitest/basictx.sh # @./clitest/ibc.sh diff --git a/clitest/basictx.sh b/clitest/basictx.sh index 0cface81f..e5e159a33 100755 --- a/clitest/basictx.sh +++ b/clitest/basictx.sh @@ -17,8 +17,6 @@ oneTimeSetUp() { # start basecoin server (with counter) initServer - sleep 5 - PID_SERVER=$! echo pid $PID_SERVER initClient @@ -30,8 +28,10 @@ oneTimeSetUp() { } oneTimeTearDown() { - echo "stopping basecoin test server" - kill -9 $PID_SERVER + echo + echo + echo "stopping basecoin test server..." + kill -9 $PID_SERVER >/dev/null 2>&1 sleep 1 } @@ -59,6 +59,8 @@ initServer() { echo "Starting server..." basecoin start --home=$SERVE_DIR >>$SERVER_LOG 2>&1 & + sleep 5 + PID_SERVER=$! } initClient() { @@ -86,22 +88,56 @@ getAddr() { echo $RAW | cut -d' ' -f2 } -testGetAccount() { +test00GetAccount() { SENDER=$(getAddr $RICH) RECV=$(getAddr $POOR) - echo sender $RICH - echo $SENDER - - echo recipient $POOR - echo $RECV - assertFalse "requires arg" "basecli query account" ACCT=$(basecli query account $SENDER) assertTrue "must have proper genesis account" $? - echo $ACCT + assertEquals "no tx" "0" $(echo $ACCT | jq .data.sequence) + assertEquals "has money" "9007199254740992" $(echo $ACCT | jq .data.coins[0].amount) + + ACCT2=$(basecli query account $RECV) + assertFalse "has no genesis account" $? } +test01SendTx() { + SENDER=$(getAddr $RICH) + RECV=$(getAddr $POOR) + + assertFalse "missing dest" "basecli tx send --amount=992mycoin --sequence=1 2>/dev/null" + assertFalse "bad password" "echo foo | basecli tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH 2>/dev/null" + # we have to remove the password request from stdout, to just get the json + RES=$(echo qwertyuiop | basecli tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH 2>/dev/null | tail -n +2) + assertTrue "sent tx" $? + HASH=$(echo $RES | jq .hash | tr -d \") + TX_HEIGHT=$(echo $RES | jq .height) + assertEquals "good check" "0" $(echo $RES | jq .check_tx.code) + assertEquals "good deliver" "0" $(echo $RES | jq .deliver_tx.code) + + # make sure sender goes down + ACCT=$(basecli query account $SENDER) + assertTrue "must have genesis account" $? + assertEquals "one tx" "1" $(echo $ACCT | jq .data.sequence) + assertEquals "has money" "9007199254740000" $(echo $ACCT | jq .data.coins[0].amount) + + # make sure recipient goes up + ACCT2=$(basecli query account $RECV) + assertTrue "must have new account" $? + assertEquals "no tx" "0" $(echo $ACCT2 | jq .data.sequence) + assertEquals "has money" "992" $(echo $ACCT2 | jq .data.coins[0].amount) + + # make sure tx is indexed + TX=$(basecli query tx $HASH) + assertTrue "found tx" $? + assertEquals "proper height" $TX_HEIGHT $(echo $TX | jq .height) + assertEquals "type=send" '"send"' $(echo $TX | jq .data.type) + assertEquals "proper sender" "\"$SENDER\"" $(echo $TX | jq .data.data.inputs[0].address) + assertEquals "proper out amount" "992" $(echo $TX | jq .data.data.outputs[0].coins[0].amount) +} + + # load and run these tests with shunit2! DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory . $DIR/shunit2 diff --git a/glide.lock b/glide.lock index bd3888209..3a7d423fa 100644 --- a/glide.lock +++ b/glide.lock @@ -127,7 +127,7 @@ imports: - data - data/base58 - name: github.com/tendermint/light-client - version: 88fb726e779d97acac5f0bd387892bfc541f3701 + version: a4dbbcacfd2d0a53da1393cbe176c0a81cab42e7 subpackages: - certifiers - certifiers/client From 6e390a6dfb1bc3d27d84ea1a4dda9585158d52b8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 15 Jun 2017 17:56:08 +0200 Subject: [PATCH 9/9] Updated to newest of develop --- glide.lock | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/glide.lock b/glide.lock index 3a7d423fa..a83da1126 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 6eb1119dccf2ab4d0adb870a14cb4408047119be53c8ec4afeaa281bd1d2b457 -updated: 2017-06-15T12:09:30.832243232+02:00 +updated: 2017-06-15T17:51:21.867322849+02:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -113,7 +113,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-crypto - version: 438b16f1f84ef002d7408ecd6fc3a3974cbc9559 + version: 7dff40942a64cdeefefa9446b2d104750b349f8a subpackages: - cmd - keys @@ -122,12 +122,12 @@ imports: - keys/server/types - keys/storage/filestorage - name: github.com/tendermint/go-wire - version: 97beaedf0f4dbc035309157c92be3b30cc6e5d74 + version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb subpackages: - data - data/base58 - name: github.com/tendermint/light-client - version: a4dbbcacfd2d0a53da1393cbe176c0a81cab42e7 + version: 83bede2a7f150fc7f8aedde1aecd30d2bdf043e8 subpackages: - certifiers - certifiers/client @@ -139,17 +139,16 @@ imports: - commands/txs - proofs - name: github.com/tendermint/merkleeyes - version: c722818b460381bc5b82e38c73ff6e22a9df624d + version: feb2c3fadac8221f96fbfce65a63af034327f972 subpackages: - app - client - iavl - name: github.com/tendermint/tendermint - version: 11b5d11e9eec170e1d3dce165f0270d5c0759d69 + version: 4f0f50c62d41d39ad64e07ad642f705cc13c8229 subpackages: - blockchain - cmd/tendermint/commands - - cmd/tendermint/commands/flags - config - consensus - mempool