diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5834035..49f48dd92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ FEATURES - You can now use a Ledger with `gaiacli --ledger` for all key-related commands - Ledger keys can be named and tracked locally in the key DB * [gaiacli] added an --async flag to the cli to deliver transactions without waiting for a tendermint response +* [gaiacli] improve error messages on `send` and `account` commands IMPROVEMENTS * bank module uses go-wire codec instead of 'encoding/json' @@ -100,6 +101,7 @@ BUG FIXES * \#1353 - CLI: Show pool shares fractions in human-readable format * \#1258 - printing big.rat's can no longer overflow int64 * \#887 - limit the size of rationals that can be passed in from user input +* \#1461 - CLI tests now no longer reset your local environment data ## 0.19.0 diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 000000000..879453988 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,512 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "github.com/bartekn/go-bip39" + packages = ["."] + revision = "a05967ea095d81c8fe4833776774cfaff8e5036c" + +[[projects]] + branch = "master" + name = "github.com/beorn7/perks" + packages = ["quantile"] + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" + +[[projects]] + name = "github.com/bgentry/speakeasy" + packages = ["."] + revision = "4aabc24848ce5fd31929f7d1e4ea74d3709c14cd" + version = "v0.1.0" + +[[projects]] + branch = "master" + name = "github.com/brejski/hid" + packages = ["."] + revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" + +[[projects]] + branch = "master" + name = "github.com/btcsuite/btcd" + packages = ["btcec"] + revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64" + +[[projects]] + branch = "master" + name = "github.com/btcsuite/btcutil" + packages = ["bech32"] + revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + branch = "master" + name = "github.com/ebuchman/fail-test" + packages = ["."] + revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" + +[[projects]] + name = "github.com/fsnotify/fsnotify" + packages = ["."] + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" + +[[projects]] + name = "github.com/go-kit/kit" + packages = [ + "log", + "log/level", + "log/term", + "metrics", + "metrics/discard", + "metrics/internal/lv", + "metrics/prometheus" + ] + revision = "4dc7be5d2d12881735283bcab7352178e190fc71" + version = "v0.6.0" + +[[projects]] + name = "github.com/go-logfmt/logfmt" + packages = ["."] + revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" + version = "v0.3.0" + +[[projects]] + name = "github.com/go-stack/stack" + packages = ["."] + revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" + version = "v1.7.0" + +[[projects]] + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "jsonpb", + "proto", + "protoc-gen-gogo/descriptor", + "sortkeys", + "types" + ] + revision = "1adfc126b41513cc696b209667c8656ea7aac67c" + version = "v1.0.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "925541529c1fa6821df4e44ce2723319eb2be768" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/golang/snappy" + packages = ["."] + revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" + +[[projects]] + name = "github.com/gorilla/context" + packages = ["."] + revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" + version = "v1.1.1" + +[[projects]] + name = "github.com/gorilla/mux" + packages = ["."] + revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" + version = "v1.6.2" + +[[projects]] + name = "github.com/gorilla/websocket" + packages = ["."] + revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" + version = "v1.2.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/printer", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token" + ] + revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" + +[[projects]] + name = "github.com/inconshreveable/mousetrap" + packages = ["."] + revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" + version = "v1.0" + +[[projects]] + branch = "master" + name = "github.com/jmhodges/levigo" + packages = ["."] + revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" + +[[projects]] + branch = "master" + name = "github.com/kr/logfmt" + packages = ["."] + revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" + +[[projects]] + name = "github.com/magiconair/properties" + packages = ["."] + revision = "c2353362d570a7bfa228149c62842019201cfb71" + version = "v1.8.0" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" + version = "v1.0.1" + +[[projects]] + branch = "master" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" + +[[projects]] + name = "github.com/pelletier/go-toml" + packages = ["."] + revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" + version = "v1.2.0" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/prometheus/client_golang" + packages = [ + "prometheus", + "prometheus/promhttp" + ] + revision = "c5b7fccd204277076155f10851dad72b76a49317" + version = "v0.8.0" + +[[projects]] + branch = "master" + name = "github.com/prometheus/client_model" + packages = ["go"] + revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" + +[[projects]] + branch = "master" + name = "github.com/prometheus/common" + packages = [ + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model" + ] + revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" + +[[projects]] + branch = "master" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/util", + "nfs", + "xfs" + ] + revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a" + +[[projects]] + branch = "master" + name = "github.com/rcrowley/go-metrics" + packages = ["."] + revision = "e2704e165165ec55d062f5919b4b29494e9fa790" + +[[projects]] + name = "github.com/spf13/afero" + packages = [ + ".", + "mem" + ] + revision = "787d034dfe70e44075ccc060d346146ef53270ad" + version = "v1.1.1" + +[[projects]] + name = "github.com/spf13/cast" + packages = ["."] + revision = "8965335b8c7107321228e3e3702cab9832751bac" + version = "v1.2.0" + +[[projects]] + name = "github.com/spf13/cobra" + packages = ["."] + revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" + version = "v0.0.1" + +[[projects]] + branch = "master" + name = "github.com/spf13/jwalterweatherman" + packages = ["."] + revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" + +[[projects]] + name = "github.com/spf13/pflag" + packages = ["."] + revision = "583c0c0531f06d5278b7d917446061adc344b5cd" + version = "v1.0.1" + +[[projects]] + name = "github.com/spf13/viper" + packages = ["."] + revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7" + version = "v1.0.0" + +[[projects]] + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require" + ] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" + +[[projects]] + branch = "master" + name = "github.com/syndtr/goleveldb" + packages = [ + "leveldb", + "leveldb/cache", + "leveldb/comparer", + "leveldb/errors", + "leveldb/filter", + "leveldb/iterator", + "leveldb/journal", + "leveldb/memdb", + "leveldb/opt", + "leveldb/storage", + "leveldb/table", + "leveldb/util" + ] + revision = "0d5a0ceb10cf9ab89fdd744cc8c50a83134f6697" + +[[projects]] + branch = "master" + name = "github.com/tendermint/ed25519" + packages = [ + ".", + "edwards25519", + "extra25519" + ] + revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" + +[[projects]] + name = "github.com/tendermint/go-amino" + packages = ["."] + revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" + version = "0.10.1" + +[[projects]] + name = "github.com/tendermint/iavl" + packages = ["."] + revision = "9e5dc3e61f70b285bb25414452d47aca1ff34c1d" + version = "v0.8.2-rc0" + +[[projects]] + name = "github.com/tendermint/tendermint" + packages = [ + "abci/client", + "abci/example/code", + "abci/example/kvstore", + "abci/server", + "abci/types", + "blockchain", + "cmd/tendermint/commands", + "config", + "consensus", + "consensus/types", + "crypto", + "crypto/merkle", + "crypto/tmhash", + "evidence", + "libs/autofile", + "libs/bech32", + "libs/cli", + "libs/cli/flags", + "libs/clist", + "libs/common", + "libs/db", + "libs/events", + "libs/flowrate", + "libs/log", + "libs/pubsub", + "libs/pubsub/query", + "lite", + "lite/client", + "lite/errors", + "lite/files", + "lite/proxy", + "mempool", + "node", + "p2p", + "p2p/conn", + "p2p/pex", + "p2p/upnp", + "privval", + "proxy", + "rpc/client", + "rpc/core", + "rpc/core/types", + "rpc/grpc", + "rpc/lib", + "rpc/lib/client", + "rpc/lib/server", + "rpc/lib/types", + "state", + "state/txindex", + "state/txindex/kv", + "state/txindex/null", + "types", + "version" + ] + revision = "5923b6288fe8ce9581936ee97c2bf9cf9c02c2f4" + version = "v0.22.0-rc2" + +[[projects]] + name = "github.com/zondax/ledger-goclient" + packages = ["."] + revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "blowfish", + "curve25519", + "internal/subtle", + "nacl/box", + "nacl/secretbox", + "openpgp/armor", + "openpgp/errors", + "pbkdf2", + "poly1305", + "ripemd160", + "salsa20/salsa" + ] + revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "http/httpguts", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "netutil", + "trace" + ] + revision = "ed29d75add3d7c4bf7ca65aac0c6df3d1420216f" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "151529c776cdc58ddbe7963ba9af779f3577b419" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "encoding/proto", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap", + "transport" + ] + revision = "d11072e7ca9811b1100b80ca0269ac831f06d024" + version = "v1.11.3" + +[[projects]] + name = "gopkg.in/yaml.v2" + packages = ["."] + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "13ad2a57b6942729e2d08b5c37810d62108aa64a335a4822fcff1ad992c0662b" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 07230a4f9..0761bd08f 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -3,6 +3,7 @@ package clitest import ( "encoding/json" "fmt" + "os" "testing" "github.com/stretchr/testify/require" @@ -21,32 +22,39 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -func TestGaiaCLISend(t *testing.T) { +var ( + pass = "1234567890" + gaiadHome = "" + gaiacliHome = "" +) - tests.ExecuteT(t, "gaiad unsafe_reset_all") - pass := "1234567890" - executeWrite(t, "gaiacli keys delete foo", pass) - executeWrite(t, "gaiacli keys delete bar", pass) - chainID := executeInit(t, "gaiad init -o --name=foo") - executeWrite(t, "gaiacli keys add bar", pass) +func init() { + gaiadHome, gaiacliHome = getTestingHomeDirs() +} + +func TestGaiaCLISend(t *testing.T) { + tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) + chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) // get a free port, also setup some common flags servAddr, port, err := server.FreeTCPAddr() require.NoError(t, err) - flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID) // start gaiad server - proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr)) + defer proc.Stop(false) tests.WaitForTMStart(port) tests.WaitForNextHeightTM(port) - fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") - fooCech, err := sdk.Bech32ifyAcc(fooAddr) - require.NoError(t, err) - barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") - barCech, err := sdk.Bech32ifyAcc(barAddr) - require.NoError(t, err) + fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome)) + fooCech := sdk.MustBech32ifyAcc(fooAddr) + barAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome)) + barCech := sdk.MustBech32ifyAcc(barAddr) fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags)) require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) @@ -79,33 +87,29 @@ func TestGaiaCLISend(t *testing.T) { } func TestGaiaCLICreateValidator(t *testing.T) { - - tests.ExecuteT(t, "gaiad unsafe_reset_all") - pass := "1234567890" - executeWrite(t, "gaiacli keys delete foo", pass) - executeWrite(t, "gaiacli keys delete bar", pass) - chainID := executeInit(t, "gaiad init -o --name=foo") - executeWrite(t, "gaiacli keys add bar", pass) + tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) + chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) // get a free port, also setup some common flags servAddr, port, err := server.FreeTCPAddr() require.NoError(t, err) - flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID) // start gaiad server - proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr)) + defer proc.Stop(false) tests.WaitForTMStart(port) tests.WaitForNextHeightTM(port) - fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") - fooCech, err := sdk.Bech32ifyAcc(fooAddr) - require.NoError(t, err) - barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") - barCech, err := sdk.Bech32ifyAcc(barAddr) - require.NoError(t, err) - barCeshPubKey, err := sdk.Bech32ifyValPub(barPubKey) - require.NoError(t, err) + fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome)) + fooCech := sdk.MustBech32ifyAcc(fooAddr) + barAddr, barPubKey := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome)) + barCech := sdk.MustBech32ifyAcc(barAddr) + barCeshPubKey := sdk.MustBech32ifyValPub(barPubKey) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass) tests.WaitForNextHeightTM(port) @@ -153,28 +157,26 @@ func TestGaiaCLICreateValidator(t *testing.T) { } func TestGaiaCLISubmitProposal(t *testing.T) { - - tests.ExecuteT(t, "gaiad unsafe_reset_all") - pass := "1234567890" - executeWrite(t, "gaiacli keys delete foo", pass) - executeWrite(t, "gaiacli keys delete bar", pass) - chainID := executeInit(t, "gaiad init -o --name=foo") - executeWrite(t, "gaiacli keys add bar", pass) + tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) + chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) + executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) // get a free port, also setup some common flags servAddr, port, err := server.FreeTCPAddr() require.NoError(t, err) - flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID) // start gaiad server - proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr)) + defer proc.Stop(false) tests.WaitForTMStart(port) tests.WaitForNextHeightTM(port) - fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") - fooCech, err := sdk.Bech32ifyAcc(fooAddr) - require.NoError(t, err) + fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome)) + fooCech := sdk.MustBech32ifyAcc(fooAddr) fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags)) require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) @@ -206,6 +208,16 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, gov.VoteOptionToString(gov.OptionYes), vote.Option) } +//___________________________________________________________________________________ +// helper methods + +func getTestingHomeDirs() (string, string) { + tmpDir := os.TempDir() + gaiadHome := fmt.Sprintf("%s%s.test_gaiad", tmpDir, string(os.PathSeparator)) + gaiacliHome := fmt.Sprintf("%s%s.test_gaiacli", tmpDir, string(os.PathSeparator)) + return gaiadHome, gaiacliHome +} + //___________________________________________________________________________________ // executors diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index 57bbfc48a..f65b9267e 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -320,7 +320,7 @@ On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond t gaiacli stake delegate \ --amount=10steak \ --address-delegator= \ - --address-validator=$(gaiad tendermint show_validator) \ + --address-validator= \ --name= \ --chain-id=gaia-6002 ``` @@ -336,7 +336,7 @@ If for any reason the validator misbehaves, or you want to unbond a certain amou ```bash gaiacli stake unbond \ --address-delegator= \ - --address-validator=$(gaiad tendermint show_validator) \ + --address-validator= \ --shares=MAX \ --name= \ --chain-id=gaia-6002 @@ -349,7 +349,7 @@ gaiacli account gaiacli stake delegation \ --address-delegator= \ - --address-validator=$(gaiad tendermint show_validator) \ + --address-validator= \ --chain-id=gaia-6002 ``` diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 0bb84c146..e74b3b700 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -29,20 +29,24 @@ func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso if err != nil { return } + key := "cool" value := json.RawMessage(`{ "trend": "ice-cold" }`) - appState, err = server.AppendJSON(cdc, appState, key, value) + + appState, err = server.InsertKeyJSON(cdc, appState, key, value) if err != nil { return } + key = "pow" value = json.RawMessage(`{ "difficulty": 1, "count": 0 }`) - appState, err = server.AppendJSON(cdc, appState, key, value) + + appState, err = server.InsertKeyJSON(cdc, appState, key, value) return } diff --git a/server/init.go b/server/init.go index 0cc99e79f..3c9186fba 100644 --- a/server/init.go +++ b/server/init.go @@ -332,32 +332,20 @@ func readOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { return privValidator.GetPubKey() } -// create the genesis file +// writeGenesisFile creates and writes the genesis configuration to disk. An +// error is returned if building or writing the configuration to file fails. func writeGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { genDoc := tmtypes.GenesisDoc{ - ChainID: chainID, - Validators: validators, + ChainID: chainID, + Validators: validators, + AppStateJSON: appState, } + if err := genDoc.ValidateAndComplete(); err != nil { return err } - if err := genDoc.SaveAs(genesisFile); err != nil { - return err - } - return addAppStateToGenesis(cdc, genesisFile, appState) -} -// Add one line to the genesis file -func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState json.RawMessage) error { - bz, err := ioutil.ReadFile(genesisConfigPath) - if err != nil { - return err - } - out, err := AppendJSON(cdc, bz, "app_state", appState) - if err != nil { - return err - } - return ioutil.WriteFile(genesisConfigPath, out, 0600) + return genDoc.SaveAs(genesisFile) } //_____________________________________________________________________ diff --git a/server/util.go b/server/util.go index d1ad001c5..0f1816b16 100644 --- a/server/util.go +++ b/server/util.go @@ -123,15 +123,21 @@ func AddCommands( //___________________________________________________________________________________ -// append a new json field to existing json message -func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) { +// InsertKeyJSON inserts a new JSON field/key with a given value to an existing +// JSON message. An error is returned if any serialization operation fails. +// +// NOTE: The ordering of the keys returned as the resulting JSON message is +// non-deterministic, so the client should not rely on key ordering. +func InsertKeyJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) ([]byte, error) { var jsonMap map[string]json.RawMessage - err = cdc.UnmarshalJSON(baseJSON, &jsonMap) - if err != nil { + + if err := cdc.UnmarshalJSON(baseJSON, &jsonMap); err != nil { return nil, err } + jsonMap[key] = value bz, err := wire.MarshalJSONIndent(cdc, jsonMap) + return json.RawMessage(bz), err } diff --git a/server/util_test.go b/server/util_test.go index 8f1ab21db..6082caa2c 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestAppendJSON(t *testing.T) { +func TestInsertKeyJSON(t *testing.T) { cdc := wire.NewCodec() foo := map[string]string{"foo": "foofoo"} @@ -24,7 +24,7 @@ func TestAppendJSON(t *testing.T) { barRaw := json.RawMessage(bz) // make the append - appBz, err := AppendJSON(cdc, fooRaw, "barOuter", barRaw) + appBz, err := InsertKeyJSON(cdc, fooRaw, "barOuter", barRaw) require.NoError(t, err) // test the append diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index ccc1e277b..47980a64c 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -54,7 +55,7 @@ func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecode // Check if account was found if res == nil { - return sdk.ErrUnknownAddress("No account with address " + addr + + return errors.New("No account with address " + addr + " was found in the state.\nAre you sure there has been a transaction involving it?") } diff --git a/x/bank/client/cli/sendtx.go b/x/bank/client/cli/sendtx.go index d3f7377fa..e3ce4c4d2 100644 --- a/x/bank/client/cli/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -9,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/bank/client" ) @@ -19,7 +21,7 @@ const ( flagAsync = "async" ) -// SendTxCommand will create a send tx and sign it with the given key +// SendTxCmd will create a send tx and sign it with the given key func SendTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "send", @@ -33,19 +35,41 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command { return err } + fromAcc, err := ctx.QueryStore(auth.AddressStoreKey(from), ctx.AccountStore) + if err != nil { + return err + } + + bech32From := sdk.MustBech32ifyAcc(from) + // Check if account was found + if fromAcc == nil { + return errors.New("No account with address " + bech32From + + " was found in the state.\nAre you sure there has been a transaction involving it?") + } + toStr := viper.GetString(flagTo) to, err := sdk.GetAccAddressBech32(toStr) if err != nil { return err } - // parse coins + // parse coins trying to be sent amount := viper.GetString(flagAmount) coins, err := sdk.ParseCoins(amount) if err != nil { return err } + // ensure account has enough coins + account, err := ctx.Decoder(fromAcc) + if err != nil { + return err + } + if !account.GetCoins().IsGTE(coins) { + return errors.New("Address " + bech32From + + " doesn't have enough coins to pay for this transaction.") + } + // build and sign the transaction, then broadcast to Tendermint msg := client.BuildMsg(from, to, coins) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 39c7771f0..82149a2fa 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -118,7 +118,7 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command { return err } - delAddr, err := sdk.GetValAddressHex(viper.GetString(FlagAddressDelegator)) + delAddr, err := sdk.GetAccAddressBech32(viper.GetString(FlagAddressDelegator)) if err != nil { return err }