From 547390a238b23024f24ee79898b4b61f783f1682 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Thu, 5 Jul 2018 17:11:44 +0100 Subject: [PATCH 1/3] WIP: add simple sorting using golang json.Marshal --- Gopkg.lock | 512 -------------------------------------------- server/util.go | 17 ++ server/util_test.go | 4 + 3 files changed, 21 insertions(+), 512 deletions(-) delete mode 100644 Gopkg.lock diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 7a9b56696..000000000 --- a/Gopkg.lock +++ /dev/null @@ -1,512 +0,0 @@ -# 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 = "40f013a808ec4fa79def444a1a56de4d1727efcb" - -[[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 = "7138fd3d9dc8335c567ca206f4333fb75eb05d56" - -[[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/server/util.go b/server/util.go index d1ad001c5..44b0d95ab 100644 --- a/server/util.go +++ b/server/util.go @@ -135,6 +135,23 @@ func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMess return json.RawMessage(bz), err } +// SortedJSON takes any JSON and returns it sorted by keys. +// This can be used to sort JSON which will be returned by GetSignBytes, +// e.g. for the ledger integration. +// If the passed JSON isn't valid this will fail. +func SortJSON(toSortJSON []byte) ([]byte, error) { + var c interface{} + err := json.Unmarshal(toSortJSON, &c) + if err != nil { + return nil, err + } + js, err := json.MarshalIndent(c, "", " ") + if err != nil { + return nil, err + } + return js, nil +} + // https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go // TODO there must be a better way to get external IP func externalIP() (string, error) { diff --git a/server/util_test.go b/server/util_test.go index 8f1ab21db..a207558f3 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -38,3 +38,7 @@ func TestAppendJSON(t *testing.T) { require.Equal(t, bar, resBar, "appended: %v", appended) } + +func TestSortJSON(t *testing.T) { + // TODO add testcases of several types +} From 97182dce21229d12c7191926829066856b6b655e Mon Sep 17 00:00:00 2001 From: Liamsi Date: Thu, 5 Jul 2018 19:09:08 +0100 Subject: [PATCH 2/3] Add test-cases, remove indentation --- server/util.go | 9 +++++---- server/util_test.go | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/server/util.go b/server/util.go index 44b0d95ab..c77222bfe 100644 --- a/server/util.go +++ b/server/util.go @@ -135,17 +135,18 @@ func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMess return json.RawMessage(bz), err } -// SortedJSON takes any JSON and returns it sorted by keys. -// This can be used to sort JSON which will be returned by GetSignBytes, +// SortedJSON takes any JSON and returns it sorted by keys. Also, all white-spaces +// are removed. +// This method can be used to canonicalize JSON to be returned by GetSignBytes, // e.g. for the ledger integration. -// If the passed JSON isn't valid this will fail. +// If the passed JSON isn't valid it will return an error. func SortJSON(toSortJSON []byte) ([]byte, error) { var c interface{} err := json.Unmarshal(toSortJSON, &c) if err != nil { return nil, err } - js, err := json.MarshalIndent(c, "", " ") + js, err := json.Marshal(c) if err != nil { return nil, err } diff --git a/server/util_test.go b/server/util_test.go index a207558f3..301215e1a 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -40,5 +40,32 @@ func TestAppendJSON(t *testing.T) { } func TestSortJSON(t *testing.T) { - // TODO add testcases of several types + cases := []struct { + unsortedJson string + want string + wantErr bool + }{ + // simple case + {unsortedJson: `{"cosmos":"foo", "atom":"bar", "tendermint":"foobar"}`, + want: `{"atom":"bar","cosmos":"foo","tendermint":"foobar"}`, wantErr: false}, + // failing case (invalid JSON): + {unsortedJson: `"cosmos":"foo",,,, "atom":"bar", "tendermint":"foobar"}`, + want: "", wantErr: true}, + // genesis.json + {unsortedJson: `{"consensus_params":{"block_size_params":{"max_bytes":22020096,"max_txs":100000,"max_gas":-1},"tx_size_params":{"max_bytes":10240,"max_gas":-1},"block_gossip_params":{"block_part_size_bytes":65536},"evidence_params":{"max_age":100000}},"validators":[{"pub_key":{"type":"AC26791624DE60","value":"c7UMMAbjFuc5GhGPy0E5q5tefy12p9Tq0imXqdrKXwo="},"power":100,"name":""}],"app_hash":"","genesis_time":"2018-05-11T15:52:25.424795506Z","chain_id":"test-chain-Q6VeoW","app_state":{"accounts":[{"address":"718C9C23F98C9642569742ADDD9F9AB9743FBD5D","coins":[{"denom":"Token","amount":1000},{"denom":"steak","amount":50}]}],"stake":{"pool":{"total_supply":50,"bonded_shares":"0","unbonded_shares":"0","bonded_pool":0,"unbonded_pool":0,"inflation_last_time":0,"inflation":"7/100"},"params":{"inflation_rate_change":"13/100","inflation_max":"1/5","inflation_min":"7/100","goal_bonded":"67/100","max_validators":100,"bond_denom":"steak"},"candidates":null,"bonds":null}}}`, + want: `{"app_hash":"","app_state":{"accounts":[{"address":"718C9C23F98C9642569742ADDD9F9AB9743FBD5D","coins":[{"amount":1000,"denom":"Token"},{"amount":50,"denom":"steak"}]}],"stake":{"bonds":null,"candidates":null,"params":{"bond_denom":"steak","goal_bonded":"67/100","inflation_max":"1/5","inflation_min":"7/100","inflation_rate_change":"13/100","max_validators":100},"pool":{"bonded_pool":0,"bonded_shares":"0","inflation":"7/100","inflation_last_time":0,"total_supply":50,"unbonded_pool":0,"unbonded_shares":"0"}}},"chain_id":"test-chain-Q6VeoW","consensus_params":{"block_gossip_params":{"block_part_size_bytes":65536},"block_size_params":{"max_bytes":22020096,"max_gas":-1,"max_txs":100000},"evidence_params":{"max_age":100000},"tx_size_params":{"max_bytes":10240,"max_gas":-1}},"genesis_time":"2018-05-11T15:52:25.424795506Z","validators":[{"name":"","power":100,"pub_key":{"type":"AC26791624DE60","value":"c7UMMAbjFuc5GhGPy0E5q5tefy12p9Tq0imXqdrKXwo="}}]}`, + wantErr: false}, + // from the TXSpec: + {unsortedJson: `{"chain_id":"test-chain-1","sequence":1,"fee_bytes":{"amount":[{"amount":5,"denom":"photon"}],"gas":10000},"msg_bytes":{"inputs":[{"address":"696E707574","coins":[{"amount":10,"denom":"atom"}]}],"outputs":[{"address":"6F7574707574","coins":[{"amount":10,"denom":"atom"}]}]},"alt_bytes":null}`, + want: `{"alt_bytes":null,"chain_id":"test-chain-1","fee_bytes":{"amount":[{"amount":5,"denom":"photon"}],"gas":10000},"msg_bytes":{"inputs":[{"address":"696E707574","coins":[{"amount":10,"denom":"atom"}]}],"outputs":[{"address":"6F7574707574","coins":[{"amount":10,"denom":"atom"}]}]},"sequence":1}`, + wantErr: false}, + } + + for _, tc := range cases { + got, err := SortJSON([]byte(tc.unsortedJson)) + if tc.wantErr != (err != nil) { + t.Fatalf("got %t, want: %t, err=%s", err != nil, tc.wantErr, err) + } + require.Equal(t, string(got), tc.want) + } } From 28245dba900b4e67a1e48381341b455d69cbaca1 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Thu, 5 Jul 2018 19:18:48 +0100 Subject: [PATCH 3/3] adhere to golint --- server/util_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/util_test.go b/server/util_test.go index 301215e1a..dc4ba75f2 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -41,28 +41,28 @@ func TestAppendJSON(t *testing.T) { func TestSortJSON(t *testing.T) { cases := []struct { - unsortedJson string + unsortedJSON string want string wantErr bool }{ // simple case - {unsortedJson: `{"cosmos":"foo", "atom":"bar", "tendermint":"foobar"}`, + {unsortedJSON: `{"cosmos":"foo", "atom":"bar", "tendermint":"foobar"}`, want: `{"atom":"bar","cosmos":"foo","tendermint":"foobar"}`, wantErr: false}, // failing case (invalid JSON): - {unsortedJson: `"cosmos":"foo",,,, "atom":"bar", "tendermint":"foobar"}`, + {unsortedJSON: `"cosmos":"foo",,,, "atom":"bar", "tendermint":"foobar"}`, want: "", wantErr: true}, // genesis.json - {unsortedJson: `{"consensus_params":{"block_size_params":{"max_bytes":22020096,"max_txs":100000,"max_gas":-1},"tx_size_params":{"max_bytes":10240,"max_gas":-1},"block_gossip_params":{"block_part_size_bytes":65536},"evidence_params":{"max_age":100000}},"validators":[{"pub_key":{"type":"AC26791624DE60","value":"c7UMMAbjFuc5GhGPy0E5q5tefy12p9Tq0imXqdrKXwo="},"power":100,"name":""}],"app_hash":"","genesis_time":"2018-05-11T15:52:25.424795506Z","chain_id":"test-chain-Q6VeoW","app_state":{"accounts":[{"address":"718C9C23F98C9642569742ADDD9F9AB9743FBD5D","coins":[{"denom":"Token","amount":1000},{"denom":"steak","amount":50}]}],"stake":{"pool":{"total_supply":50,"bonded_shares":"0","unbonded_shares":"0","bonded_pool":0,"unbonded_pool":0,"inflation_last_time":0,"inflation":"7/100"},"params":{"inflation_rate_change":"13/100","inflation_max":"1/5","inflation_min":"7/100","goal_bonded":"67/100","max_validators":100,"bond_denom":"steak"},"candidates":null,"bonds":null}}}`, + {unsortedJSON: `{"consensus_params":{"block_size_params":{"max_bytes":22020096,"max_txs":100000,"max_gas":-1},"tx_size_params":{"max_bytes":10240,"max_gas":-1},"block_gossip_params":{"block_part_size_bytes":65536},"evidence_params":{"max_age":100000}},"validators":[{"pub_key":{"type":"AC26791624DE60","value":"c7UMMAbjFuc5GhGPy0E5q5tefy12p9Tq0imXqdrKXwo="},"power":100,"name":""}],"app_hash":"","genesis_time":"2018-05-11T15:52:25.424795506Z","chain_id":"test-chain-Q6VeoW","app_state":{"accounts":[{"address":"718C9C23F98C9642569742ADDD9F9AB9743FBD5D","coins":[{"denom":"Token","amount":1000},{"denom":"steak","amount":50}]}],"stake":{"pool":{"total_supply":50,"bonded_shares":"0","unbonded_shares":"0","bonded_pool":0,"unbonded_pool":0,"inflation_last_time":0,"inflation":"7/100"},"params":{"inflation_rate_change":"13/100","inflation_max":"1/5","inflation_min":"7/100","goal_bonded":"67/100","max_validators":100,"bond_denom":"steak"},"candidates":null,"bonds":null}}}`, want: `{"app_hash":"","app_state":{"accounts":[{"address":"718C9C23F98C9642569742ADDD9F9AB9743FBD5D","coins":[{"amount":1000,"denom":"Token"},{"amount":50,"denom":"steak"}]}],"stake":{"bonds":null,"candidates":null,"params":{"bond_denom":"steak","goal_bonded":"67/100","inflation_max":"1/5","inflation_min":"7/100","inflation_rate_change":"13/100","max_validators":100},"pool":{"bonded_pool":0,"bonded_shares":"0","inflation":"7/100","inflation_last_time":0,"total_supply":50,"unbonded_pool":0,"unbonded_shares":"0"}}},"chain_id":"test-chain-Q6VeoW","consensus_params":{"block_gossip_params":{"block_part_size_bytes":65536},"block_size_params":{"max_bytes":22020096,"max_gas":-1,"max_txs":100000},"evidence_params":{"max_age":100000},"tx_size_params":{"max_bytes":10240,"max_gas":-1}},"genesis_time":"2018-05-11T15:52:25.424795506Z","validators":[{"name":"","power":100,"pub_key":{"type":"AC26791624DE60","value":"c7UMMAbjFuc5GhGPy0E5q5tefy12p9Tq0imXqdrKXwo="}}]}`, wantErr: false}, // from the TXSpec: - {unsortedJson: `{"chain_id":"test-chain-1","sequence":1,"fee_bytes":{"amount":[{"amount":5,"denom":"photon"}],"gas":10000},"msg_bytes":{"inputs":[{"address":"696E707574","coins":[{"amount":10,"denom":"atom"}]}],"outputs":[{"address":"6F7574707574","coins":[{"amount":10,"denom":"atom"}]}]},"alt_bytes":null}`, + {unsortedJSON: `{"chain_id":"test-chain-1","sequence":1,"fee_bytes":{"amount":[{"amount":5,"denom":"photon"}],"gas":10000},"msg_bytes":{"inputs":[{"address":"696E707574","coins":[{"amount":10,"denom":"atom"}]}],"outputs":[{"address":"6F7574707574","coins":[{"amount":10,"denom":"atom"}]}]},"alt_bytes":null}`, want: `{"alt_bytes":null,"chain_id":"test-chain-1","fee_bytes":{"amount":[{"amount":5,"denom":"photon"}],"gas":10000},"msg_bytes":{"inputs":[{"address":"696E707574","coins":[{"amount":10,"denom":"atom"}]}],"outputs":[{"address":"6F7574707574","coins":[{"amount":10,"denom":"atom"}]}]},"sequence":1}`, wantErr: false}, } for _, tc := range cases { - got, err := SortJSON([]byte(tc.unsortedJson)) + got, err := SortJSON([]byte(tc.unsortedJSON)) if tc.wantErr != (err != nil) { t.Fatalf("got %t, want: %t, err=%s", err != nil, tc.wantErr, err) }