diff --git a/.circleci/config.yml b/.circleci/config.yml index c194aa84f..d866bd637 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -178,7 +178,7 @@ jobs: name: Test multi-seed Gaia simulation command: | export PATH="$GOBIN:$PATH" - make test_sim_gaia_multi_seed + scripts/multisim.sh 25 TestFullGaiaSimulation test_cover: <<: *defaults diff --git a/CHANGELOG.md b/CHANGELOG.md index 7894748a4..2ff20a938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # Changelog +## 0.28.0 + +BREAKING CHANGES + +* Gaia CLI (`gaiacli`) + * [cli] [\#2595](https://github.com/cosmos/cosmos-sdk/issues/2595) Remove `keys new` in favor of `keys add` incorporating existing functionality with addition of key recovery functionality. + * [cli] [\#2987](https://github.com/cosmos/cosmos-sdk/pull/2987) Add shorthand `-a` to `gaiacli keys show` and update docs + * [cli] [\#2971](https://github.com/cosmos/cosmos-sdk/pull/2971) Additional verification when running `gaiad gentx` + * [cli] [\#2734](https://github.com/cosmos/cosmos-sdk/issues/2734) Rewrite `gaiacli config`. It is now a non-interactive config utility. + +* Gaia + * [#128](https://github.com/tendermint/devops/issues/128) Updated CircleCI job to trigger website build on every push to master/develop. + * [\#2994](https://github.com/cosmos/cosmos-sdk/pull/2994) Change wrong-password error message. + * [\#3009](https://github.com/cosmos/cosmos-sdk/issues/3009) Added missing Gaia genesis verification + * [#128](https://github.com/tendermint/devops/issues/128) Updated CircleCI job to trigger website build on every push to master/develop. + * [\#2994](https://github.com/cosmos/cosmos-sdk/pull/2994) Change wrong-password error message. + * [\#3009](https://github.com/cosmos/cosmos-sdk/issues/3009) Added missing Gaia genesis verification + * [gas] [\#3052](https://github.com/cosmos/cosmos-sdk/issues/3052) Updated gas costs to more reasonable numbers + +* SDK + * [auth] [\#2952](https://github.com/cosmos/cosmos-sdk/issues/2952) Signatures are no longer serialized on chain with the account number and sequence number + * [auth] [\#2952](https://github.com/cosmos/cosmos-sdk/issues/2952) Signatures are no longer serialized on chain with the account number and sequence number + * [stake] [\#3055](https://github.com/cosmos/cosmos-sdk/issues/3055) Use address instead of bond height / intratxcounter for deduplication + +FEATURES + +* Gaia CLI (`gaiacli`) + * [\#2961](https://github.com/cosmos/cosmos-sdk/issues/2961) Add --force flag to gaiacli keys delete command to skip passphrase check and force key deletion unconditionally. + +IMPROVEMENTS + +* Gaia CLI (`gaiacli`) + * [\#2991](https://github.com/cosmos/cosmos-sdk/issues/2991) Fully validate transaction signatures during `gaiacli tx sign --validate-signatures` + +* SDK + * [\#1277](https://github.com/cosmos/cosmos-sdk/issues/1277) Complete bank module specification + * [\#2963](https://github.com/cosmos/cosmos-sdk/issues/2963) Complete auth module specification + * [\#2914](https://github.com/cosmos/cosmos-sdk/issues/2914) No longer withdraw validator rewards on bond/unbond, but rather move + the rewards to the respective validator's pools. + + +BUG FIXES + +* Gaia CLI (`gaiacli`) + * [\#2921](https://github.com/cosmos/cosmos-sdk/issues/2921) Fix `keys delete` inability to delete offline and ledger keys. + +* Gaia + * [\#3003](https://github.com/cosmos/cosmos-sdk/issues/3003) CollectStdTxs() must validate DelegatorAddr against genesis accounts. + +* SDK + * [\#2967](https://github.com/cosmos/cosmos-sdk/issues/2967) Change ordering of `mint.BeginBlocker` and `distr.BeginBlocker`, recalculate inflation each block + * [\#3068](https://github.com/cosmos/cosmos-sdk/issues/3068) check for uint64 gas overflow during `Std#ValidateBasic`. + * [\#3071](https://github.com/cosmos/cosmos-sdk/issues/3071) Catch overflow on block gas meter + + ## 0.27.0 BREAKING CHANGES diff --git a/PENDING.md b/PENDING.md index 95ecba5b5..9a5f51d8a 100644 --- a/PENDING.md +++ b/PENDING.md @@ -3,22 +3,15 @@ BREAKING CHANGES * Gaia REST API (`gaiacli advanced rest-server`) + * [lcd] https://github.com/cosmos/cosmos-sdk/pull/3045 Fix quoted json return on GET /keys (keys list) + * [gaia-lite] [\#2191](https://github.com/cosmos/cosmos-sdk/issues/2191) Split `POST /stake/delegators/{delegatorAddr}/delegations` into `POST /stake/delegators/{delegatorAddr}/delegations`, `POST /stake/delegators/{delegatorAddr}/unbonding_delegations` and `POST /stake/delegators/{delegatorAddr}/redelegations` + * [gaia-lite] [\#3056](https://github.com/cosmos/cosmos-sdk/pull/3056) `generate_only` and `simulate` have moved from query arguments to POST requests body. * Gaia CLI (`gaiacli`) - * [cli] [\#2595](https://github.com/cosmos/cosmos-sdk/issues/2595) Remove `keys new` in favor of `keys add` incorporating existing functionality with addition of key recovery functionality. - * [cli] [\#2987](https://github.com/cosmos/cosmos-sdk/pull/2987) Add shorthand `-a` to `gaiacli keys show` and update docs - * [cli] [\#2971](https://github.com/cosmos/cosmos-sdk/pull/2971) Additional verification when running `gaiad gentx` - * [cli] [\#2734](https://github.com/cosmos/cosmos-sdk/issues/2734) Rewrite `gaiacli config`. It is now a non-interactive config utility. * Gaia - - [#128](https://github.com/tendermint/devops/issues/128) Updated CircleCI job to trigger website build on every push to master/develop. - - [\#2994](https://github.com/cosmos/cosmos-sdk/pull/2994) Change wrong-password error message. - - \#3009 Added missing Gaia genesis verification - - [gas] \#3052 Updated gas costs to more reasonable numbers * SDK - - [auth] \#2952 Signatures are no longer serialized on chain with the account number and sequence number - - [stake] \#3055 Use address instead of bond height / intratxcounter for deduplication * Tendermint @@ -28,10 +21,8 @@ FEATURES * Gaia REST API (`gaiacli advanced rest-server`) * Gaia CLI (`gaiacli`) - - [\#2961](https://github.com/cosmos/cosmos-sdk/issues/2961) Add --force flag to gaiacli keys delete command to skip passphrase check and force key deletion unconditionally. * Gaia - - [gov] Added minimum quorum needed for vote to pass * SDK @@ -43,15 +34,12 @@ IMPROVEMENTS * Gaia REST API (`gaiacli advanced rest-server`) * Gaia CLI (`gaiacli`) - * \#2991 Fully validate transaction signatures during `gaiacli tx sign --validate-signatures` * Gaia + * [\#3021](https://github.com/cosmos/cosmos-sdk/pull/3021) Add `--gentx-dir` to `gaiad collect-gentxs` to specify a directory from which collect and load gentxs. + Add `--output-document` to `gaiad init` to allow one to redirect output to file. * SDK - - \#1277 Complete bank module specification - - \#2963 Complete auth module specification - * \#2914 No longer withdraw validator rewards on bond/unbond, but rather move - the rewards to the respective validator's pools. * Tendermint @@ -61,12 +49,9 @@ BUG FIXES * Gaia REST API (`gaiacli advanced rest-server`) * Gaia CLI (`gaiacli`) - * [\#2921](https://github.com/cosmos/cosmos-sdk/issues/2921) Fix `keys delete` inability to delete offline and ledger keys. * Gaia - * [\#3003](https://github.com/cosmos/cosmos-sdk/issues/3003) CollectStdTxs() must validate DelegatorAddr against genesis accounts. * SDK - * \#2967 Change ordering of `mint.BeginBlocker` and `distr.BeginBlocker`, recalculate inflation each block * Tendermint diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index eeeea53da..c3042b588 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -701,6 +701,11 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk return } + var startingGas uint64 + if mode == runTxModeDeliver { + startingGas = ctx.BlockGasMeter().GasConsumed() + } + defer func() { if r := recover(); r != nil { switch rType := r.(type) { @@ -726,6 +731,9 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk if mode == runTxModeDeliver { ctx.BlockGasMeter().ConsumeGas( ctx.GasMeter().GasConsumedToLimit(), "block gas meter") + if ctx.BlockGasMeter().GasConsumed() < startingGas { + panic(sdk.ErrorGasOverflow{"tx gas summation"}) + } } }() diff --git a/baseapp/helpers.go b/baseapp/helpers.go index f3f1448bc..b6a0a3612 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,10 +1,11 @@ package baseapp import ( - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/abci/server" abci "github.com/tendermint/tendermint/abci/types" cmn "github.com/tendermint/tendermint/libs/common" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // nolint - Mostly for testing diff --git a/baseapp/options.go b/baseapp/options.go index 8d86933a0..6e4104e50 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -4,9 +4,10 @@ package baseapp import ( "fmt" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - dbm "github.com/tendermint/tendermint/libs/db" ) // File for storing in-package BaseApp optional functions, diff --git a/baseapp/query_test.go b/baseapp/query_test.go index d9d4001eb..fed7ae477 100644 --- a/baseapp/query_test.go +++ b/baseapp/query_test.go @@ -4,9 +4,10 @@ import ( "fmt" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // Test that we can only query from the latest committed state. diff --git a/client/config.go b/client/config.go index 51d6da700..ab72ee78d 100644 --- a/client/config.go +++ b/client/config.go @@ -7,9 +7,10 @@ import ( "path" "strconv" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/tendermint/tendermint/libs/cli" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/pelletier/go-toml" "github.com/spf13/cobra" "github.com/spf13/viper" diff --git a/client/context/context.go b/client/context/context.go index 4b4407368..9fac7c27a 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -13,14 +13,15 @@ import ( "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client/keys" - cskeys "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" tmlite "github.com/tendermint/tendermint/lite" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" + + "github.com/cosmos/cosmos-sdk/client/keys" + cskeys "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/types" ) const ctxAccStoreName = "acc" @@ -46,7 +47,7 @@ type CLIContext struct { JSON bool PrintResponse bool Verifier tmlite.Verifier - DryRun bool + Simulate bool GenerateOnly bool fromAddress types.AccAddress fromName string @@ -84,7 +85,7 @@ func NewCLIContext() CLIContext { JSON: viper.GetBool(client.FlagJson), PrintResponse: viper.GetBool(client.FlagPrintResponse), Verifier: verifier, - DryRun: viper.GetBool(client.FlagDryRun), + Simulate: viper.GetBool(client.FlagDryRun), GenerateOnly: viper.GetBool(client.FlagGenerateOnly), fromAddress: fromAddress, fromName: fromName, @@ -243,3 +244,15 @@ func (ctx CLIContext) WithVerifier(verifier tmlite.Verifier) CLIContext { ctx.Verifier = verifier return ctx } + +// WithGenerateOnly returns a copy of the context with updated GenerateOnly value +func (ctx CLIContext) WithGenerateOnly(generateOnly bool) CLIContext { + ctx.GenerateOnly = generateOnly + return ctx +} + +// WithSimulation returns a copy of the context with updated Simulate value +func (ctx CLIContext) WithSimulation(simulate bool) CLIContext { + ctx.Simulate = simulate + return ctx +} diff --git a/client/context/errors.go b/client/context/errors.go index de96aaa18..f28454ca0 100644 --- a/client/context/errors.go +++ b/client/context/errors.go @@ -1,8 +1,9 @@ package context import ( - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/pkg/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // ErrInvalidAccount returns a standardized error reflecting that a given diff --git a/client/context/query.go b/client/context/query.go index 486bd5186..0eff95d30 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -10,7 +10,6 @@ import ( "strings" - "github.com/cosmos/cosmos-sdk/store" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" @@ -18,6 +17,8 @@ import ( tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/store" ) // GetNode returns an RPC client. If the context's client is not defined, an diff --git a/client/flags.go b/client/flags.go index 6a3ccff06..cf7be359e 100644 --- a/client/flags.go +++ b/client/flags.go @@ -43,6 +43,7 @@ const ( FlagSSLHosts = "ssl-hosts" FlagSSLCertFile = "ssl-certfile" FlagSSLKeyFile = "ssl-keyfile" + FlagOutputDocument = "output-document" // inspired by wget -O ) // LineBreak can be included in a command list to provide a blank line diff --git a/client/keys.go b/client/keys.go index a39b074b9..1fc594a2a 100644 --- a/client/keys.go +++ b/client/keys.go @@ -1,8 +1,9 @@ package client import ( - "github.com/cosmos/cosmos-sdk/crypto/keys" dbm "github.com/tendermint/tendermint/libs/db" + + "github.com/cosmos/cosmos-sdk/crypto/keys" ) // GetKeyBase initializes a keybase based on the given db. diff --git a/client/keys/delete.go b/client/keys/delete.go index e3fac4b7f..5f3ff4f09 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -10,10 +10,11 @@ import ( "github.com/spf13/viper" + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client" keys "github.com/cosmos/cosmos-sdk/crypto/keys" keyerror "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" - "github.com/gorilla/mux" "github.com/spf13/cobra" ) diff --git a/client/keys/list.go b/client/keys/list.go index f232fccff..9d01d500b 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -50,7 +50,7 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc { } // an empty list will be JSONized as null, but we want to keep the empty list if len(infos) == 0 { - PostProcessResponse(w, cdc, "[]", indent) + PostProcessResponse(w, cdc, []string{}, indent) return } keysOutput, err := Bech32KeysOutput(infos) diff --git a/client/keys/mnemonic.go b/client/keys/mnemonic.go index 33270a087..32a6856bb 100644 --- a/client/keys/mnemonic.go +++ b/client/keys/mnemonic.go @@ -4,9 +4,10 @@ import ( "crypto/sha256" "fmt" - "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client" + bip39 "github.com/bartekn/go-bip39" ) diff --git a/client/keys/root.go b/client/keys/root.go index bca6f50e8..f747d84a0 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -1,9 +1,10 @@ package keys import ( - "github.com/cosmos/cosmos-sdk/client" "github.com/gorilla/mux" "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" ) // Commands registers a sub-tree of commands to interact with diff --git a/client/keys/show.go b/client/keys/show.go index d539eb3b7..9583dd07a 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -4,17 +4,19 @@ import ( "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/tendermint/tendermint/crypto" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tendermint/tendermint/crypto/multisig" "github.com/tendermint/tendermint/libs/cli" + + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( diff --git a/client/keys/update.go b/client/keys/update.go index 2489bce12..e72da240c 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -5,12 +5,14 @@ import ( "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/client" - keys "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/gorilla/mux" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" + "github.com/cosmos/cosmos-sdk/client" + keys "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) func updateKeyCommand() *cobra.Command { diff --git a/client/keys/utils.go b/client/keys/utils.go index 0ac4a9c90..78899f5f8 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -5,14 +5,15 @@ import ( "net/http" "path/filepath" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/viper" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/tendermint/tendermint/libs/cli" dbm "github.com/tendermint/tendermint/libs/db" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys" + sdk "github.com/cosmos/cosmos-sdk/types" ) // KeyDBName is the directory under root where we store the keys diff --git a/client/keys/utils_test.go b/client/keys/utils_test.go index 6b65bb55a..5f3dd4560 100644 --- a/client/keys/utils_test.go +++ b/client/keys/utils_test.go @@ -1,11 +1,13 @@ package keys import ( - "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/stretchr/testify/require" "io/ioutil" "os" "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/crypto/keys" ) func TestGetKeyBaseLocks(t *testing.T) { diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 04453111a..164edb0f3 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -7,121 +7,86 @@ import ( "net/http" "os" "regexp" - "strings" "testing" "time" "github.com/spf13/viper" "github.com/stretchr/testify/require" - p2p "github.com/tendermint/tendermint/p2p" ctypes "github.com/tendermint/tendermint/rpc/core/types" client "github.com/cosmos/cosmos-sdk/client" - keys "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/codec" - cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" tests "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" - version "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" "github.com/cosmos/cosmos-sdk/x/gov" - "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" ) +const ( + name1 = "test1" + name2 = "test2" + name3 = "test3" + pw = app.DefaultKeyPass + altPw = "12345678901" +) + func init() { mintkey.BcryptSecurityParameter = 1 version.Version = os.Getenv("VERSION") } func TestKeys(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, _ := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() - // get seed - // TODO Do we really need this endpoint? - res, body := Request(t, port, "GET", "/keys/seed", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - reg, err := regexp.Compile(`([a-z]+ ){12}`) - require.Nil(t, err) - match := reg.MatchString(seed) - require.True(t, match, "Returned seed has wrong format", seed) + // get new seed + seed := getKeysSeed(t, port) // recover key - recoverName := "test_recovername" - recoverPassword := "1234567890" - doRecoverKey(t, port, recoverName, recoverPassword, seed) + doRecoverKey(t, port, name2, pw, seed) - newName := "test_newname" - newPassword := "0987654321" // add key - jsonStr := []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed":"%s"}`, newName, newPassword, seed)) - res, body = Request(t, port, "POST", "/keys", jsonStr) - - require.Equal(t, http.StatusOK, res.StatusCode, body) - var resp keys.KeyOutput - err = codec.Cdc.UnmarshalJSON([]byte(body), &resp) - require.Nil(t, err, body) + resp := doKeysPost(t, port, name3, pw, seed) + addrBech32 := addr.String() addr2Bech32 := resp.Address - _, err = sdk.AccAddressFromBech32(addr2Bech32) + _, err := sdk.AccAddressFromBech32(addr2Bech32) require.NoError(t, err, "Failed to return a correct bech32 address") // test if created account is the correct account - expectedInfo, _ := GetKeyBase(t).CreateKey(newName, seed, newPassword) + expectedInfo, _ := GetKeyBase(t).CreateKey(name3, seed, pw) expectedAccount := sdk.AccAddress(expectedInfo.GetPubKey().Address().Bytes()) require.Equal(t, expectedAccount.String(), addr2Bech32) // existing keys - res, body = Request(t, port, "GET", "/keys", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var m [3]keys.KeyOutput - err = cdc.UnmarshalJSON([]byte(body), &m) - require.Nil(t, err) - - addrBech32 := addr.String() - - require.Equal(t, name, m[0].Name, "Did not serve keys name correctly") - require.Equal(t, addrBech32, m[0].Address, "Did not serve keys Address correctly") - require.Equal(t, newName, m[1].Name, "Did not serve keys name correctly") - require.Equal(t, addr2Bech32, m[1].Address, "Did not serve keys Address correctly") + keys := getKeys(t, port) + require.Equal(t, name1, keys[0].Name, "Did not serve keys name correctly") + require.Equal(t, addrBech32, keys[0].Address, "Did not serve keys Address correctly") + require.Equal(t, name2, keys[1].Name, "Did not serve keys name correctly") + require.Equal(t, addr2Bech32, keys[1].Address, "Did not serve keys Address correctly") // select key - keyEndpoint := fmt.Sprintf("/keys/%s", newName) - res, body = Request(t, port, "GET", keyEndpoint, nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var m2 keys.KeyOutput - err = cdc.UnmarshalJSON([]byte(body), &m2) - require.Nil(t, err) - - require.Equal(t, newName, m2.Name, "Did not serve keys name correctly") - require.Equal(t, addr2Bech32, m2.Address, "Did not serve keys Address correctly") + key := getKey(t, port, name3) + require.Equal(t, name3, key.Name, "Did not serve keys name correctly") + require.Equal(t, addr2Bech32, key.Address, "Did not serve keys Address correctly") // update key - jsonStr = []byte(fmt.Sprintf(`{ - "old_password":"%s", - "new_password":"12345678901" - }`, newPassword)) - - res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) + updateKey(t, port, name3, pw, altPw, false) // here it should say unauthorized as we changed the password before - res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) - require.Equal(t, http.StatusUnauthorized, res.StatusCode, body) + updateKey(t, port, name3, pw, altPw, true) // delete key - jsonStr = []byte(`{"password":"12345678901"}`) - res, body = Request(t, port, "DELETE", keyEndpoint, jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) + deleteKey(t, port, name3, altPw) } func TestVersion(t *testing.T) { @@ -155,91 +120,30 @@ func TestVersion(t *testing.T) { func TestNodeStatus(t *testing.T) { cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) defer cleanup() - - // node info - res, body := Request(t, port, "GET", "/node_info", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var nodeInfo p2p.DefaultNodeInfo - err := cdc.UnmarshalJSON([]byte(body), &nodeInfo) - require.Nil(t, err, "Couldn't parse node info") - - require.NotEqual(t, p2p.DefaultNodeInfo{}, nodeInfo, "res: %v", res) - - // syncing - res, body = Request(t, port, "GET", "/syncing", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - // we expect that there is no other node running so the syncing state is "false" - require.Equal(t, "false", body) + getNodeInfo(t, port) + getSyncStatus(t, port, false) } func TestBlock(t *testing.T) { cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) defer cleanup() - - var resultBlock ctypes.ResultBlock - - res, body := Request(t, port, "GET", "/blocks/latest", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err := cdc.UnmarshalJSON([]byte(body), &resultBlock) - require.Nil(t, err, "Couldn't parse block") - - require.NotEqual(t, ctypes.ResultBlock{}, resultBlock) - - // -- - - res, body = Request(t, port, "GET", "/blocks/2", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err = codec.Cdc.UnmarshalJSON([]byte(body), &resultBlock) - require.Nil(t, err, "Couldn't parse block") - - require.NotEqual(t, ctypes.ResultBlock{}, resultBlock) - - // -- - - res, body = Request(t, port, "GET", "/blocks/1000000000", nil) - require.Equal(t, http.StatusNotFound, res.StatusCode, body) + getBlock(t, port, -1, false) + getBlock(t, port, 2, false) + getBlock(t, port, 100000000, true) } func TestValidators(t *testing.T) { cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) defer cleanup() - - var resultVals rpc.ResultValidatorsOutput - - res, body := Request(t, port, "GET", "/validatorsets/latest", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err := cdc.UnmarshalJSON([]byte(body), &resultVals) - require.Nil(t, err, "Couldn't parse validatorset") - - require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) - + resultVals := getValidatorSets(t, port, -1, false) require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvaloper") require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalconspub") - - // -- - - res, body = Request(t, port, "GET", "/validatorsets/2", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err = cdc.UnmarshalJSON([]byte(body), &resultVals) - require.Nil(t, err, "Couldn't parse validatorset") - - require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) - - // -- - - res, body = Request(t, port, "GET", "/validatorsets/1000000000", nil) - require.Equal(t, http.StatusNotFound, res.StatusCode, body) + getValidatorSets(t, port, 2, false) + getValidatorSets(t, port, 10000000, true) } func TestCoinSend(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() @@ -255,7 +159,7 @@ func TestCoinSend(t *testing.T) { initialBalance := acc.GetCoins() // create TX - receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) + receiveAddr, resultTx := doTransfer(t, port, seed, name1, pw, addr) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was committed @@ -279,70 +183,40 @@ func TestCoinSend(t *testing.T) { require.Equal(t, int64(1), mycoins.Amount.Int64()) // test failure with too little gas - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, "100", 0, "") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "100", 0, false, false) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) // test failure with negative gas - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, "-200", 0, "") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "-200", 0, false, false) require.Equal(t, http.StatusBadRequest, res.StatusCode, body) // test failure with 0 gas - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, "0", 0, "") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "0", 0, false, false) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) // test failure with wrong adjustment - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, "simulate", 0.1, "") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "simulate", 0.1, false, false) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) // run simulation and test success with estimated gas - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, "", 0, "?simulate=true") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "", 0, true, false) require.Equal(t, http.StatusOK, res.StatusCode, body) var responseBody struct { GasEstimate int64 `json:"gas_estimate"` } require.Nil(t, json.Unmarshal([]byte(body), &responseBody)) - res, body, _ = doSendWithGas(t, port, seed, name, password, addr, fmt.Sprintf("%v", responseBody.GasEstimate), 0, "") + res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, fmt.Sprintf("%v", responseBody.GasEstimate), 0, false, false) require.Equal(t, http.StatusOK, res.StatusCode, body) } -func DisabledTestIBCTransfer(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) - defer cleanup() - - acc := getAccount(t, port, addr) - initialBalance := acc.GetCoins() - - // create TX - resultTx := doIBCTransfer(t, port, seed, name, password, addr) - - tests.WaitForHeight(resultTx.Height+1, port) - - // check if tx was committed - require.Equal(t, uint32(0), resultTx.CheckTx.Code) - require.Equal(t, uint32(0), resultTx.DeliverTx.Code) - - // query sender - acc = getAccount(t, port, addr) - coins := acc.GetCoins() - mycoins := coins[0] - - require.Equal(t, stakeTypes.DefaultBondDenom, mycoins.Denom) - require.Equal(t, initialBalance[0].Amount.SubRaw(1), mycoins.Amount) - - // TODO: query ibc egress packet state -} - func TestCoinSendGenerateSignAndBroadcast(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() acc := getAccount(t, port, addr) // generate TX - res, body, _ := doSendWithGas(t, port, seed, name, password, addr, "simulate", 0, "?generate_only=true") + res, body, _ := doTransferWithGas(t, port, seed, name1, pw, addr, "simulate", 0, false, true) require.Equal(t, http.StatusOK, res.StatusCode, body) var msg auth.StdTx require.Nil(t, cdc.UnmarshalJSON([]byte(body), &msg)) @@ -351,16 +225,16 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) { require.Equal(t, msg.Msgs[0].GetSigners(), []sdk.AccAddress{addr}) require.Equal(t, 0, len(msg.Signatures)) gasEstimate := msg.Fee.Gas - - // sign tx - var signedMsg auth.StdTx accnum := acc.GetAccountNumber() sequence := acc.GetSequence() + // sign tx + var signedMsg auth.StdTx + payload := authrest.SignBody{ Tx: msg, - LocalAccountName: name, - Password: password, + LocalAccountName: name1, + Password: pw, ChainID: viper.GetString(client.FlagChainID), AccountNumber: accnum, Sequence: sequence, @@ -395,8 +269,7 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) { } func TestTxs(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() @@ -416,13 +289,12 @@ func TestTxs(t *testing.T) { require.Equal(t, emptyTxs, txs) // create tx - receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) + receiveAddr, resultTx := doTransfer(t, port, seed, name1, pw, addr) tests.WaitForHeight(resultTx.Height+1, port) // check if tx is queryable - txs = getTransactions(t, port, fmt.Sprintf("tx.hash=%s", resultTx.Hash)) - require.Len(t, txs, 1) - require.Equal(t, resultTx.Hash, txs[0].Hash) + tx := getTransaction(t, port, resultTx.Hash.String()) + require.Equal(t, resultTx.Hash, tx.Hash) // query sender txs = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String())) @@ -436,33 +308,22 @@ func TestTxs(t *testing.T) { } func TestPoolParamsQuery(t *testing.T) { - _, password := "test", "1234567890" - addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, _ := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() defaultParams := stake.DefaultParams() - res, body := Request(t, port, "GET", "/stake/parameters", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var params stake.Params - err := cdc.UnmarshalJSON([]byte(body), ¶ms) - require.Nil(t, err) + params := getStakeParams(t, port) require.True(t, defaultParams.Equal(params)) - res, body = Request(t, port, "GET", "/stake/pool", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - require.NotNil(t, body) + pool := getStakePool(t, port) initialPool := stake.InitialPool() initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(100)) initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(int64(50))) // freeFermionsAcc = 50 on GaiaAppGenState - var pool stake.Pool - err = cdc.UnmarshalJSON([]byte(body), &pool) - require.Nil(t, err) require.Equal(t, initialPool.BondedTokens, pool.BondedTokens) require.Equal(t, initialPool.LooseTokens, pool.LooseTokens) } @@ -498,8 +359,7 @@ func TestValidatorQuery(t *testing.T) { } func TestBonding(t *testing.T) { - name, password, denom := "test", "1234567890", stakeTypes.DefaultBondDenom - addr, seed := CreateAddr(t, name, password, GetKeyBase(t)) + addr, _ := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, valPubKeys, operAddrs, port := InitializeTestLCD(t, 2, []sdk.AccAddress{addr}) defer cleanup() @@ -511,7 +371,7 @@ func TestBonding(t *testing.T) { validator := getValidator(t, port, operAddrs[0]) // create bond TX - resultTx := doDelegate(t, port, seed, name, password, addr, operAddrs[0], 60) + resultTx := doDelegate(t, port, name1, pw, addr, operAddrs[0], 60) tests.WaitForHeight(resultTx.Height+1, port) require.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -528,7 +388,7 @@ func TestBonding(t *testing.T) { acc := getAccount(t, port, addr) coins := acc.GetCoins() - require.Equal(t, int64(40), coins.AmountOf(denom).Int64()) + require.Equal(t, int64(40), coins.AmountOf(stakeTypes.DefaultBondDenom).Int64()) // query delegation bond := getDelegation(t, port, addr, operAddrs[0]) @@ -551,7 +411,7 @@ func TestBonding(t *testing.T) { require.Equal(t, operAddrs[0], bondedValidator.OperatorAddr) // testing unbonding - resultTx = doBeginUnbonding(t, port, seed, name, password, addr, operAddrs[0], 30) + resultTx = doBeginUnbonding(t, port, name1, pw, addr, operAddrs[0], 30) tests.WaitForHeight(resultTx.Height+1, port) require.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -574,7 +434,7 @@ func TestBonding(t *testing.T) { require.Equal(t, "30", unbonding.Balance.Amount.String()) // test redelegation - resultTx = doBeginRedelegation(t, port, seed, name, password, addr, operAddrs[0], operAddrs[1], 30) + resultTx = doBeginRedelegation(t, port, name1, pw, addr, operAddrs[0], operAddrs[1], 30) tests.WaitForHeight(resultTx.Height+1, port) require.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -628,13 +488,12 @@ func TestBonding(t *testing.T) { } func TestSubmitProposal(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() // create SubmitProposal TX - resultTx := doSubmitProposal(t, port, seed, name, password, addr, 5) + resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was committed @@ -655,13 +514,12 @@ func TestSubmitProposal(t *testing.T) { } func TestDeposit(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() // create SubmitProposal TX - resultTx := doSubmitProposal(t, port, seed, name, password, addr, 5) + resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was committed @@ -676,7 +534,7 @@ func TestDeposit(t *testing.T) { require.Equal(t, "Test", proposal.GetTitle()) // create SubmitProposal TX - resultTx = doDeposit(t, port, seed, name, password, addr, proposalID, 5) + resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, 5) tests.WaitForHeight(resultTx.Height+1, port) // query tx @@ -694,13 +552,12 @@ func TestDeposit(t *testing.T) { } func TestVote(t *testing.T) { - name, password := "test", "1234567890" - addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, _, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() // create SubmitProposal TX - resultTx := doSubmitProposal(t, port, seed, name, password, addr, 5) + resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was committed @@ -715,7 +572,7 @@ func TestVote(t *testing.T) { require.Equal(t, "Test", proposal.GetTitle()) // deposit - resultTx = doDeposit(t, port, seed, name, password, addr, proposalID, 5) + resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, 5) tests.WaitForHeight(resultTx.Height+1, port) // query proposal @@ -723,7 +580,7 @@ func TestVote(t *testing.T) { require.Equal(t, gov.StatusVotingPeriod, proposal.GetStatus()) // vote - resultTx = doVote(t, port, seed, name, password, addr, proposalID) + resultTx = doVote(t, port, seed, name1, pw, addr, proposalID) tests.WaitForHeight(resultTx.Height+1, port) // query tx @@ -739,11 +596,11 @@ func TestVote(t *testing.T) { require.Equal(t, sdk.ZeroDec(), tally.Yes, "tally should be 0 as the address is not bonded") // create bond TX - resultTx = doDelegate(t, port, seed, name, password, addr, operAddrs[0], 60) + resultTx = doDelegate(t, port, name1, pw, addr, operAddrs[0], 60) tests.WaitForHeight(resultTx.Height+1, port) // vote - resultTx = doVote(t, port, seed, name, password, addr, proposalID) + resultTx = doVote(t, port, seed, name1, pw, addr, proposalID) tests.WaitForHeight(resultTx.Height+1, port) tally = getTally(t, port, proposalID) @@ -751,8 +608,7 @@ func TestVote(t *testing.T) { } func TestUnjail(t *testing.T) { - _, password := "test", "1234567890" - addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) + addr, _ := CreateAddr(t, name1, pw, GetKeyBase(t)) cleanup, valPubKeys, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() @@ -885,677 +741,3 @@ func TestProposalsQuery(t *testing.T) { require.True(t, addrs[0].String() == votes[0].Voter.String() || addrs[0].String() == votes[1].Voter.String()) require.True(t, addrs[1].String() == votes[0].Voter.String() || addrs[1].String() == votes[1].Voter.String()) } - -//_____________________________________________________________________________ -// get the account to get the sequence -func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account { - res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", addr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var acc auth.Account - err := cdc.UnmarshalJSON([]byte(body), &acc) - require.Nil(t, err) - return acc -} - -func doSendWithGas(t *testing.T, port, seed, name, password string, addr sdk.AccAddress, gas string, gasAdjustment float64, queryStr string) (res *http.Response, body string, receiveAddr sdk.AccAddress) { - - // create receive address - kb := client.MockKeyBase() - receiveInfo, _, err := kb.CreateMnemonic("receive_address", cryptoKeys.English, "1234567890", cryptoKeys.SigningAlgo("secp256k1")) - require.Nil(t, err) - receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address()) - - acc := getAccount(t, port, addr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - chainID := viper.GetString(client.FlagChainID) - // send - coinbz, err := cdc.MarshalJSON(sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 1)) - if err != nil { - panic(err) - } - - gasStr := "" - if len(gas) != 0 { - gasStr = fmt.Sprintf(` - "gas":%q, - `, gas) - } - gasAdjustmentStr := "" - if gasAdjustment > 0 { - gasAdjustmentStr = fmt.Sprintf(` - "gas_adjustment":"%v", - `, gasAdjustment) - } - jsonStr := []byte(fmt.Sprintf(`{ - "amount":[%s], - "base_req": { - %v%v - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, coinbz, gasStr, gasAdjustmentStr, name, password, chainID, accnum, sequence)) - - res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers%v", receiveAddr, queryStr), jsonStr) - return -} - -func doRecoverKey(t *testing.T, port, recoverName, recoverPassword, seed string) { - jsonStr := []byte(fmt.Sprintf(`{"password":"%s", "seed":"%s"}`, recoverPassword, seed)) - res, body := Request(t, port, "POST", fmt.Sprintf("/keys/%s/recover", recoverName), jsonStr) - - require.Equal(t, http.StatusOK, res.StatusCode, body) - var resp keys.KeyOutput - err := codec.Cdc.UnmarshalJSON([]byte(body), &resp) - require.Nil(t, err, body) - - addr1Bech32 := resp.Address - _, err = sdk.AccAddressFromBech32(addr1Bech32) - require.NoError(t, err, "Failed to return a correct bech32 address") -} - -func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) { - res, body, receiveAddr := doSendWithGas(t, port, seed, name, password, addr, "", 0, "") - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err := cdc.UnmarshalJSON([]byte(body), &resultTx) - require.Nil(t, err) - - return receiveAddr, resultTx -} - -func getTransactions(t *testing.T, port string, tags ...string) []tx.Info { - var txs []tx.Info - if len(tags) == 0 { - return txs - } - queryStr := strings.Join(tags, "&") - res, body := Request(t, port, "GET", fmt.Sprintf("/txs?%s", queryStr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err := cdc.UnmarshalJSON([]byte(body), &txs) - require.NoError(t, err) - return txs -} - -// ============= IBC Module ================ - -func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) { - // create receive address - kb := client.MockKeyBase() - receiveInfo, _, err := kb.CreateMnemonic("receive_address", cryptoKeys.English, "1234567890", cryptoKeys.SigningAlgo("secp256k1")) - require.Nil(t, err) - receiveAddr := sdk.AccAddress(receiveInfo.GetPubKey().Address()) - - chainID := viper.GetString(client.FlagChainID) - - // get the account to get the sequence - acc := getAccount(t, port, addr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - // send - jsonStr := []byte(fmt.Sprintf(`{ - "amount":[ - { - "denom": "%s", - "amount": "1" - } - ], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, stakeTypes.DefaultBondDenom, name, password, chainID, accnum, sequence)) - - res, body := Request(t, port, "POST", fmt.Sprintf("/ibc/testchain/%s/send", receiveAddr), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err = cdc.UnmarshalJSON([]byte(body), &resultTx) - require.Nil(t, err) - - return resultTx -} - -// ============= Slashing Module ================ - -func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo { - res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/validators/%s/signing_info", validatorPubKey), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var signingInfo slashing.ValidatorSigningInfo - err := cdc.UnmarshalJSON([]byte(body), &signingInfo) - require.Nil(t, err) - - return signingInfo -} - -func doUnjail(t *testing.T, port, seed, name, password string, - valAddr sdk.ValAddress) (resultTx ctypes.ResultBroadcastTxCommit) { - chainID := viper.GetString(client.FlagChainID) - - jsonStr := []byte(fmt.Sprintf(`{ - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"1", - "sequence":"1" - } - }`, name, password, chainID)) - - res, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), jsonStr) - // TODO : fails with "401 must use own validator address" - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results []ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results[0] -} - -// ============= Stake Module ================ - -func getDelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Delegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var bond stake.Delegation - err := cdc.UnmarshalJSON([]byte(body), &bond) - require.Nil(t, err) - - return bond -} - -func getUndelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.UnbondingDelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var unbond stake.UnbondingDelegation - err := cdc.UnmarshalJSON([]byte(body), &unbond) - require.Nil(t, err) - - return unbond -} - -func getDelegatorDelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Delegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var dels []stake.Delegation - - err := cdc.UnmarshalJSON([]byte(body), &dels) - require.Nil(t, err) - - return dels -} - -func getDelegatorUnbondingDelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.UnbondingDelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations", delegatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var ubds []stake.UnbondingDelegation - - err := cdc.UnmarshalJSON([]byte(body), &ubds) - require.Nil(t, err) - - return ubds -} - -func getDelegatorRedelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Redelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/redelegations", delegatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var reds []stake.Redelegation - - err := cdc.UnmarshalJSON([]byte(body), &reds) - require.Nil(t, err) - - return reds -} - -func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info { - var res *http.Response - var body string - - if len(query) > 0 { - res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil) - } else { - res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil) - } - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var txs []tx.Info - - err := cdc.UnmarshalJSON([]byte(body), &txs) - require.Nil(t, err) - - return txs -} - -func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Validator { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators", delegatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var bondedValidators []stake.Validator - - err := cdc.UnmarshalJSON([]byte(body), &bondedValidators) - require.Nil(t, err) - - return bondedValidators -} - -func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Validator { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var bondedValidator stake.Validator - err := cdc.UnmarshalJSON([]byte(body), &bondedValidator) - require.Nil(t, err) - - return bondedValidator -} - -func doDelegate(t *testing.T, port, seed, name, password string, - delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { - - acc := getAccount(t, port, delAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - chainID := viper.GetString(client.FlagChainID) - - jsonStr := []byte(fmt.Sprintf(`{ - "delegations": [ - { - "delegator_addr": "%s", - "validator_addr": "%s", - "delegation": { "denom": "%s", "amount": "%d" } - } - ], - "begin_unbondings": [], - "begin_redelegates": [], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, delAddr, valAddr, stakeTypes.DefaultBondDenom, amount, name, password, chainID, accnum, sequence)) - - res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results []ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results[0] -} - -func doBeginUnbonding(t *testing.T, port, seed, name, password string, - delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { - - acc := getAccount(t, port, delAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - chainID := viper.GetString(client.FlagChainID) - - jsonStr := []byte(fmt.Sprintf(`{ - "delegations": [], - "begin_unbondings": [ - { - "delegator_addr": "%s", - "validator_addr": "%s", - "shares": "%d" - } - ], - "begin_redelegates": [], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, delAddr, valAddr, amount, name, password, chainID, accnum, sequence)) - - res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results []ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results[0] -} - -func doBeginRedelegation(t *testing.T, port, seed, name, password string, - delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { - - acc := getAccount(t, port, delAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - chainID := viper.GetString(client.FlagChainID) - - jsonStr := []byte(fmt.Sprintf(`{ - "delegations": [], - "begin_unbondings": [], - "begin_redelegates": [ - { - "delegator_addr": "%s", - "validator_src_addr": "%s", - "validator_dst_addr": "%s", - "shares": "%d" - } - ], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, delAddr, valSrcAddr, valDstAddr, amount, name, password, chainID, accnum, sequence)) - - res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results []ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results[0] -} - -func getValidators(t *testing.T, port string) []stake.Validator { - res, body := Request(t, port, "GET", "/stake/validators", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var validators []stake.Validator - err := cdc.UnmarshalJSON([]byte(body), &validators) - require.Nil(t, err) - - return validators -} - -func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake.Validator { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var validator stake.Validator - err := cdc.UnmarshalJSON([]byte(body), &validator) - require.Nil(t, err) - - return validator -} - -func getValidatorDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Delegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/delegations", validatorAddr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var delegations []stake.Delegation - err := cdc.UnmarshalJSON([]byte(body), &delegations) - require.Nil(t, err) - - return delegations -} - -func getValidatorUnbondingDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.UnbondingDelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/unbonding_delegations", validatorAddr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var ubds []stake.UnbondingDelegation - err := cdc.UnmarshalJSON([]byte(body), &ubds) - require.Nil(t, err) - - return ubds -} - -func getValidatorRedelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Redelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/redelegations", validatorAddr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var reds []stake.Redelegation - err := cdc.UnmarshalJSON([]byte(body), &reds) - require.Nil(t, err) - - return reds -} - -// ============= Governance Module ================ - -func getDepositParam(t *testing.T, port string) gov.DepositParams { - res, body := Request(t, port, "GET", "/gov/parameters/deposit", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var depositParams gov.DepositParams - err := cdc.UnmarshalJSON([]byte(body), &depositParams) - require.Nil(t, err) - return depositParams -} - -func getVotingParam(t *testing.T, port string) gov.VotingParams { - res, body := Request(t, port, "GET", "/gov/parameters/voting", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var votingParams gov.VotingParams - err := cdc.UnmarshalJSON([]byte(body), &votingParams) - require.Nil(t, err) - return votingParams -} - -func getTallyingParam(t *testing.T, port string) gov.TallyParams { - res, body := Request(t, port, "GET", "/gov/parameters/tallying", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var tallyParams gov.TallyParams - err := cdc.UnmarshalJSON([]byte(body), &tallyParams) - require.Nil(t, err) - return tallyParams -} - -func getProposal(t *testing.T, port string, proposalID uint64) gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d", proposalID), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var proposal gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposal) - require.Nil(t, err) - return proposal -} - -func getDeposits(t *testing.T, port string, proposalID uint64) []gov.Deposit { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var deposits []gov.Deposit - err := cdc.UnmarshalJSON([]byte(body), &deposits) - require.Nil(t, err) - return deposits -} - -func getDeposit(t *testing.T, port string, proposalID uint64, depositorAddr sdk.AccAddress) gov.Deposit { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits/%s", proposalID, depositorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var deposit gov.Deposit - err := cdc.UnmarshalJSON([]byte(body), &deposit) - require.Nil(t, err) - return deposit -} - -func getVote(t *testing.T, port string, proposalID uint64, voterAddr sdk.AccAddress) gov.Vote { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes/%s", proposalID, voterAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var vote gov.Vote - err := cdc.UnmarshalJSON([]byte(body), &vote) - require.Nil(t, err) - return vote -} - -func getVotes(t *testing.T, port string, proposalID uint64) []gov.Vote { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var votes []gov.Vote - err := cdc.UnmarshalJSON([]byte(body), &votes) - require.Nil(t, err) - return votes -} - -func getTally(t *testing.T, port string, proposalID uint64) gov.TallyResult { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/tally", proposalID), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var tally gov.TallyResult - err := cdc.UnmarshalJSON([]byte(body), &tally) - require.Nil(t, err) - return tally -} - -func getProposalsAll(t *testing.T, port string) []gov.Proposal { - res, body := Request(t, port, "GET", "/gov/proposals", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var proposals []gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposals) - require.Nil(t, err) - return proposals -} - -func getProposalsFilterDepositor(t *testing.T, port string, depositorAddr sdk.AccAddress) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s", depositorAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var proposals []gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposals) - require.Nil(t, err) - return proposals -} - -func getProposalsFilterVoter(t *testing.T, port string, voterAddr sdk.AccAddress) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?voter=%s", voterAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var proposals []gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposals) - require.Nil(t, err) - return proposals -} - -func getProposalsFilterVoterDepositor(t *testing.T, port string, voterAddr, depositorAddr sdk.AccAddress) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s&voter=%s", depositorAddr, voterAddr), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var proposals []gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposals) - require.Nil(t, err) - return proposals -} - -func getProposalsFilterStatus(t *testing.T, port string, status gov.ProposalStatus) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?status=%s", status), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var proposals []gov.Proposal - err := cdc.UnmarshalJSON([]byte(body), &proposals) - require.Nil(t, err) - return proposals -} - -func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { - - acc := getAccount(t, port, proposerAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - chainID := viper.GetString(client.FlagChainID) - - // submitproposal - jsonStr := []byte(fmt.Sprintf(`{ - "title": "Test", - "description": "test", - "proposal_type": "Text", - "proposer": "%s", - "initial_deposit": [{ "denom": "%s", "amount": "%d" }], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence":"%d" - } - }`, proposerAddr, stakeTypes.DefaultBondDenom, amount, name, password, chainID, accnum, sequence)) - res, body := Request(t, port, "POST", "/gov/proposals", jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results -} - -func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { - - acc := getAccount(t, port, proposerAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - chainID := viper.GetString(client.FlagChainID) - - // deposit on proposal - jsonStr := []byte(fmt.Sprintf(`{ - "depositor": "%s", - "amount": [{ "denom": "%s", "amount": "%d" }], - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number":"%d", - "sequence": "%d" - } - }`, proposerAddr, stakeTypes.DefaultBondDenom, amount, name, password, chainID, accnum, sequence)) - res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results -} - -func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64) (resultTx ctypes.ResultBroadcastTxCommit) { - // get the account to get the sequence - acc := getAccount(t, port, proposerAddr) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - chainID := viper.GetString(client.FlagChainID) - - // vote on proposal - jsonStr := []byte(fmt.Sprintf(`{ - "voter": "%s", - "option": "Yes", - "base_req": { - "name": "%s", - "password": "%s", - "chain_id": "%s", - "account_number": "%d", - "sequence": "%d" - } - }`, proposerAddr, name, password, chainID, accnum, sequence)) - res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), jsonStr) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var results ctypes.ResultBroadcastTxCommit - err := cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) - - return results -} diff --git a/client/lcd/root.go b/client/lcd/root.go index 00dab053e..ad7ba2ff0 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -7,12 +7,6 @@ import ( "net/http" "os" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/codec" - keybase "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/server" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cobra" @@ -20,6 +14,13 @@ import ( "github.com/tendermint/tendermint/libs/log" rpcserver "github.com/tendermint/tendermint/rpc/lib/server" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/codec" + keybase "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/server" + // Import statik for light client stuff _ "github.com/cosmos/cosmos-sdk/client/lcd/statik" ) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 82e7c3429..a76bdddd6 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -376,16 +376,6 @@ paths: produces: - application/json parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - in: path name: address description: Account address in bech32 format @@ -635,81 +625,6 @@ paths: description: Bech32 AccAddress of Delegator required: true type: string - post: - summary: Submit delegation - parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - - in: body - name: delegation - description: The password of the account to remove from the KMS - schema: - type: object - properties: - base_req: - "$ref": "#/definitions/BaseReq" - delegations: - type: array - items: - type: object - properties: - delegator_addr: - $ref: "#/definitions/Address" - validator_addr: - $ref: "#/definitions/ValidatorAddress" - delegation: - $ref: "#/definitions/Coin" - begin_unbondings: - type: array - items: - type: object - properties: - delegator_addr: - $ref: "#/definitions/Address" - validator_addr: - $ref: "#/definitions/ValidatorAddress" - shares: - type: string - example: "100" - begin_redelegates: - type: array - items: - type: object - properties: - delegator_addr: - $ref: "#/definitions/Address" - validator_src_addr: - $ref: "#/definitions/ValidatorAddress" - validator_dst_addr: - $ref: "#/definitions/ValidatorAddress" - shares: - type: string - example: "100" - tags: - - ICS21 - consumes: - - application/json - produces: - - application/json - responses: - 200: - description: OK - schema: - $ref: "#/definitions/BroadcastTxCommitResult" - 400: - description: Invalid delegator address or delegation body - 401: - description: Key password is wrong - 500: - description: Internal Server Error get: summary: Get all delegations from a delegator tags: @@ -722,12 +637,72 @@ paths: schema: type: array items: - type: object - "$ref": "#/definitions/Delegation" + $ref: "#/definitions/Delegation" 400: description: Invalid delegator address 500: description: Internal Server Error + post: + summary: Submit delegation + parameters: + - in: body + name: delegation + description: The password of the account to remove from the KMS + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + delegator_addr: + $ref: "#/definitions/Address" + validator_addr: + $ref: "#/definitions/ValidatorAddress" + delegation: + $ref: "#/definitions/Coin" + tags: + - ICS21 + consumes: + - application/json + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid delegator address or delegation request body + 401: + description: Key password is wrong + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + - in: path + name: validatorAddr + description: Bech32 OperatorAddress of validator + required: true + type: string + get: + summary: Query the current delegation between a delegator and a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/Delegation" + 400: + description: Invalid delegator address or validator address + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/unbonding_delegations: parameters: - in: path @@ -747,12 +722,85 @@ paths: schema: type: array items: - type: object - "$ref": "#/definitions/UnbondingDelegation" + $ref: "#/definitions/UnbondingDelegation" 400: description: Invalid delegator address 500: description: Internal Server Error + post: + summary: Submit an unbonding delegation + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - in: body + name: delegation + description: The password of the account to remove from the KMS + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + delegator_addr: + $ref: "#/definitions/Address" + validator_addr: + $ref: "#/definitions/ValidatorAddress" + shares: + type: string + example: "100" + tags: + - ICS21 + consumes: + - application/json + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid delegator address or unbonding delegation request body + 401: + description: Key password is wrong + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + - in: path + name: validatorAddr + description: Bech32 OperatorAddress of validator + required: true + type: string + get: + summary: Query all unbonding delegations between a delegator and a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/UnbondingDelegation" + 400: + description: Invalid delegator address or validator address + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/redelegations: parameters: - in: path @@ -772,12 +820,58 @@ paths: schema: type: array items: - type: object - "$ref": "#/definitions/Redelegation" + $ref: "#/definitions/Redelegation" 400: description: Invalid delegator address 500: description: Internal Server Error + post: + summary: Submit a redelegation + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - in: body + name: delegation + description: The password of the account to remove from the KMS + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + delegator_addr: + $ref: "#/definitions/Address" + validator_src_addr: + $ref: "#/definitions/ValidatorAddress" + validator_dst_addr: + $ref: "#/definitions/ValidatorAddress" + shares: + type: string + example: "100" + tags: + - ICS21 + consumes: + - application/json + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid delegator address or redelegation request body + 401: + description: Key password is wrong + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/validators: parameters: - in: path @@ -855,63 +949,6 @@ paths: description: Invalid delegator address 500: description: Internal Server Error - /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}: - parameters: - - in: path - name: delegatorAddr - description: Bech32 AccAddress of Delegator - required: true - type: string - - in: path - name: validatorAddr - description: Bech32 OperatorAddress of validator - required: true - type: string - get: - summary: Query the current delegation between a delegator and a validator - tags: - - ICS21 - produces: - - application/json - responses: - 200: - description: OK - schema: - $ref: "#/definitions/Delegation" - 400: - description: Invalid delegator address or validator address - 500: - description: Internal Server Error - /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: - parameters: - - in: path - name: delegatorAddr - description: Bech32 AccAddress of Delegator - required: true - type: string - - in: path - name: validatorAddr - description: Bech32 OperatorAddress of validator - required: true - type: string - get: - summary: Query all unbonding delegations between a delegator and a validator - tags: - - ICS21 - produces: - - application/json - responses: - 200: - description: OK - schema: - type: array - items: - type: object - "$ref": "#/definitions/UnbondingDelegation" - 400: - description: Invalid delegator address or validator address - 500: - description: Internal Server Error /stake/validators: get: summary: Get all validator candidates @@ -1123,16 +1160,6 @@ paths: tags: - ICS23 parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - type: string description: Bech32 validator address name: validatorAddr @@ -1146,7 +1173,7 @@ paths: type: object properties: base_req: - "$ref": "#/definitions/BaseReq" + $ref: "#/definitions/BaseReq" responses: 200: description: OK @@ -1169,16 +1196,6 @@ paths: tags: - ICS22 parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - description: valid value of `"proposal_type"` can be `"text"`, `"parameter_change"`, `"software_upgrade"` name: post_proposal_body in: body @@ -1187,7 +1204,7 @@ paths: type: object properties: base_req: - "$ref": "#/definitions/BaseReq" + $ref: "#/definitions/BaseReq" title: type: string description: @@ -1196,7 +1213,7 @@ paths: type: string example: "text" proposer: - "$ref": "#/definitions/Address" + $ref: "#/definitions/Address" initial_deposit: type: array items: @@ -1205,7 +1222,7 @@ paths: 200: description: OK schema: - "$ref": "#/definitions/BroadcastTxCommitResult" + $ref: "#/definitions/BroadcastTxCommitResult" 400: description: Invalid proposal body 401: @@ -1241,184 +1258,11 @@ paths: schema: type: array items: - "$ref": "#/definitions/TextProposal" + $ref: "#/definitions/TextProposal" 400: description: Invalid query parameters 500: description: Internal Server Error - /gov/proposals/{proposalId}/deposits: - post: - summary: Deposit tokens to a proposal - description: Send transaction to deposit tokens to a proposal - consumes: - - application/json - produces: - - application/json - tags: - - ICS22 - parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - - type: string - description: proposal id - name: proposalId - required: true - in: path - - description: '' - name: post_deposit_body - in: body - required: true - schema: - type: object - properties: - base_req: - "$ref": "#/definitions/BaseReq" - depositor: - "$ref": "#/definitions/Address" - amount: - type: array - items: - $ref: "#/definitions/Coin" - responses: - 200: - description: OK - schema: - "$ref": "#/definitions/BroadcastTxCommitResult" - 400: - description: Invalid proposal id or deposit body - 401: - description: Key password is wrong - 500: - description: Internal Server Error - get: - summary: Query deposits - description: Query deposits by proposalId - produces: - - application/json - tags: - - ICS22 - parameters: - - type: string - name: proposalId - required: true - in: path - responses: - 200: - description: OK - schema: - type: array - items: - "$ref": "#/definitions/Deposit" - 400: - description: Invalid proposal id - 500: - description: Internal Server Error - /gov/proposals/{proposalId}/tally: - get: - summary: Get a proposal's tally result at the current time - description: Gets a proposal's tally result at the current time. If the proposal is pending deposits (i.e status 'DepositPeriod') it returns an empty tally result. - produces: - - application/json - tags: - - ICS22 - parameters: - - type: string - description: proposal id - name: proposalId - required: true - in: path - responses: - 200: - description: OK - schema: - $ref: "#/definitions/TallyResult" - 400: - description: Invalid proposal id - 500: - description: Internal Server Error - /gov/proposals/{proposalId}/votes: - post: - summary: Vote a proposal - description: Send transaction to vote a proposal - consumes: - - application/json - produces: - - application/json - tags: - - ICS22 - parameters: - - in: query - name: simulate - description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it - required: false - type: boolean - - in: query - name: generate_only - description: if true, build an unsigned transaction and write it back - required: false - type: boolean - - type: string - description: proposal id - name: proposalId - required: true - in: path - - description: valid value of `"option"` field can be `"yes"`, `"no"`, `"no_with_veto"` and `"abstain"` - name: post_vote_body - in: body - required: true - schema: - type: object - properties: - base_req: - "$ref": "#/definitions/BaseReq" - voter: - "$ref": "#/definitions/Address" - option: - type: string - example: "yes" - responses: - 200: - description: OK - schema: - "$ref": "#/definitions/BroadcastTxCommitResult" - 400: - description: Invalid proposal id or vote body - 401: - description: Key password is wrong - 500: - description: Internal Server Error - get: - summary: Query voters - description: Query voters information by proposalId - produces: - - application/json - tags: - - ICS22 - parameters: - - type: string - description: proposal id - name: proposalId - required: true - in: path - responses: - 200: - description: OK - schema: - type: array - items: - "$ref": "#/definitions/Vote" - 400: - description: Invalid proposal id - 500: - description: Internal Server Error /gov/proposals/{proposalId}: get: summary: Query a proposal @@ -1436,11 +1280,76 @@ paths: 200: description: OK schema: - "$ref": "#/definitions/TextProposal" + $ref: "#/definitions/TextProposal" 400: description: Invalid proposal id 500: description: Internal Server Error + /gov/proposals/{proposalId}/deposits: + get: + summary: Query deposits + description: Query deposits by proposalId + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/Deposit" + 400: + description: Invalid proposal id + 500: + description: Internal Server Error + post: + summary: Deposit tokens to a proposal + description: Send transaction to deposit tokens to a proposal + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + description: proposal id + name: proposalId + required: true + in: path + - description: '' + name: post_deposit_body + in: body + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + depositor: + $ref: "#/definitions/Address" + amount: + type: array + items: + $ref: "#/definitions/Coin" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid proposal id or deposit body + 401: + description: Key password is wrong + 500: + description: Internal Server Error /gov/proposals/{proposalId}/deposits/{depositor}: get: summary: Query deposit @@ -1471,6 +1380,71 @@ paths: description: Found no deposit 500: description: Internal Server Error + /gov/proposals/{proposalId}/votes: + get: + summary: Query voters + description: Query voters information by proposalId + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + description: proposal id + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/Vote" + 400: + description: Invalid proposal id + 500: + description: Internal Server Error + post: + summary: Vote a proposal + description: Send transaction to vote a proposal + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + description: proposal id + name: proposalId + required: true + in: path + - description: valid value of `"option"` field can be `"yes"`, `"no"`, `"no_with_veto"` and `"abstain"` + name: post_vote_body + in: body + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + voter: + $ref: "#/definitions/Address" + option: + type: string + example: "yes" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid proposal id or vote body + 401: + description: Key password is wrong + 500: + description: Internal Server Error /gov/proposals/{proposalId}/votes/{voter}: get: summary: Query vote @@ -1501,6 +1475,29 @@ paths: description: Found no vote 500: description: Internal Server Error + /gov/proposals/{proposalId}/tally: + get: + summary: Get a proposal's tally result at the current time + description: Gets a proposal's tally result at the current time. If the proposal is pending deposits (i.e status 'DepositPeriod') it returns an empty tally result. + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + description: proposal id + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + $ref: "#/definitions/TallyResult" + 400: + description: Invalid proposal id + 500: + description: Internal Server Error /gov/parameters/deposit: get: summary: Query governance deposit parameters @@ -1598,7 +1595,7 @@ definitions: tags: type: array items: - "$ref": "#/definitions/KVPair" + $ref: "#/definitions/KVPair" example: code: 0 data: data @@ -1627,7 +1624,7 @@ definitions: tags: type: array items: - "$ref": "#/definitions/KVPair" + $ref: "#/definitions/KVPair" example: code: 5 data: data @@ -1888,6 +1885,12 @@ definitions: gas_adjustment: type: string example: "1.2" + generate_only: + type: boolean + example: false + simulate: + type: boolean + example: true TendermintValidator: type: object properties: @@ -1922,7 +1925,7 @@ definitions: total_deposit: type: array items: - "$ref": "#/definitions/Coin" + $ref: "#/definitions/Coin" voting_start_time: type: string Deposit: @@ -1931,11 +1934,11 @@ definitions: amount: type: array items: - "$ref": "#/definitions/Coin" + $ref: "#/definitions/Coin" proposal_id: type: integer depositor: - "$ref": "#/definitions/Address" + $ref: "#/definitions/Address" TallyResult: type: object properties: diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 921dc96dd..58b8426e5 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "regexp" "io/ioutil" "net" @@ -14,13 +15,19 @@ import ( "strings" "testing" + cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys" + authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/slashing" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/tendermint/tendermint/crypto/secp256k1" + ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/client/utils" gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" crkeys "github.com/cosmos/cosmos-sdk/crypto/keys" @@ -33,7 +40,6 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - txbuilder "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" abci "github.com/tendermint/tendermint/abci/types" tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" @@ -48,6 +54,8 @@ import ( tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" + txbuilder "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" + authRest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" bankRest "github.com/cosmos/cosmos-sdk/x/bank/client/rest" govRest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" @@ -196,6 +204,7 @@ func (b AddrSeedSlice) Swap(i, j int) { b[j], b[i] = b[i], b[j] } +// TODO: Make InitializeTestLCD safe to call in multiple tests at the same time // InitializeTestLCD starts Tendermint and the LCD in process, listening on // their respective sockets where nValidators is the total number of validators // and initAddrs are the accounts to initialize with some steak tokens. It @@ -392,7 +401,7 @@ func Request(t *testing.T, port, method, path string, payload []byte) (*http.Res res *http.Response ) url := fmt.Sprintf("http://localhost:%v%v", port, path) - fmt.Println("REQUEST " + method + " " + url) + fmt.Printf("REQUEST %s %s\n", method, url) req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) require.Nil(t, err) @@ -406,3 +415,956 @@ func Request(t *testing.T, port, method, path string, payload []byte) (*http.Res return res, string(output) } + +// ---------------------------------------------------------------------- +// ICS 0 - Tendermint +// ---------------------------------------------------------------------- +// GET /node_info The properties of the connected node +func getNodeInfo(t *testing.T, port string) p2p.DefaultNodeInfo { + res, body := Request(t, port, "GET", "/node_info", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var nodeInfo p2p.DefaultNodeInfo + err := cdc.UnmarshalJSON([]byte(body), &nodeInfo) + require.Nil(t, err, "Couldn't parse node info") + + require.NotEqual(t, p2p.DefaultNodeInfo{}, nodeInfo, "res: %v", res) + return nodeInfo +} + +// GET /syncing Syncing state of node +func getSyncStatus(t *testing.T, port string, syncing bool) { + res, body := Request(t, port, "GET", "/syncing", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + if syncing { + require.Equal(t, "true", body) + return + } + require.Equal(t, "false", body) +} + +// GET /blocks/latest Get the latest block +// GET /blocks/{height} Get a block at a certain height +func getBlock(t *testing.T, port string, height int, expectFail bool) ctypes.ResultBlock { + var url string + if height > 0 { + url = fmt.Sprintf("/blocks/%d", height) + } else { + url = "/blocks/latest" + } + var resultBlock ctypes.ResultBlock + + res, body := Request(t, port, "GET", url, nil) + if expectFail { + require.Equal(t, http.StatusNotFound, res.StatusCode, body) + return resultBlock + } + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err := cdc.UnmarshalJSON([]byte(body), &resultBlock) + require.Nil(t, err, "Couldn't parse block") + + require.NotEqual(t, ctypes.ResultBlock{}, resultBlock) + return resultBlock +} + +// GET /validatorsets/{height} Get a validator set a certain height +// GET /validatorsets/latest Get the latest validator set +func getValidatorSets(t *testing.T, port string, height int, expectFail bool) rpc.ResultValidatorsOutput { + var url string + if height > 0 { + url = fmt.Sprintf("/validatorsets/%d", height) + } else { + url = "/validatorsets/latest" + } + var resultVals rpc.ResultValidatorsOutput + + res, body := Request(t, port, "GET", url, nil) + + if expectFail { + require.Equal(t, http.StatusNotFound, res.StatusCode, body) + return resultVals + } + + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err := cdc.UnmarshalJSON([]byte(body), &resultVals) + require.Nil(t, err, "Couldn't parse validatorset") + + require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) + return resultVals +} + +// GET /txs/{hash} get tx by hash +func getTransaction(t *testing.T, port string, hash string) tx.Info { + var tx tx.Info + res, body := Request(t, port, "GET", fmt.Sprintf("/txs/%s", hash), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err := cdc.UnmarshalJSON([]byte(body), &tx) + require.NoError(t, err) + return tx +} + +// POST /txs broadcast txs + +// GET /txs search transactions +func getTransactions(t *testing.T, port string, tags ...string) []tx.Info { + var txs []tx.Info + if len(tags) == 0 { + return txs + } + queryStr := strings.Join(tags, "&") + res, body := Request(t, port, "GET", fmt.Sprintf("/txs?%s", queryStr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err := cdc.UnmarshalJSON([]byte(body), &txs) + require.NoError(t, err) + return txs +} + +// ---------------------------------------------------------------------- +// ICS 1 - Keys +// ---------------------------------------------------------------------- +// GET /keys List of accounts stored locally +func getKeys(t *testing.T, port string) []keys.KeyOutput { + res, body := Request(t, port, "GET", "/keys", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var m []keys.KeyOutput + err := cdc.UnmarshalJSON([]byte(body), &m) + require.Nil(t, err) + return m +} + +// POST /keys Create a new account locally +func doKeysPost(t *testing.T, port, name, password, seed string) keys.KeyOutput { + pk := postKeys{name, password, seed} + req, err := cdc.MarshalJSON(pk) + require.NoError(t, err) + res, body := Request(t, port, "POST", "/keys", req) + + require.Equal(t, http.StatusOK, res.StatusCode, body) + var resp keys.KeyOutput + err = cdc.UnmarshalJSON([]byte(body), &resp) + require.Nil(t, err, body) + return resp +} + +type postKeys struct { + Name string `json:"name"` + Password string `json:"password"` + Seed string `json:"seed"` +} + +// GET /keys/seed Create a new seed to create a new account defaultValidFor +func getKeysSeed(t *testing.T, port string) string { + res, body := Request(t, port, "GET", "/keys/seed", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + reg, err := regexp.Compile(`([a-z]+ ){12}`) + require.Nil(t, err) + match := reg.MatchString(body) + require.True(t, match, "Returned seed has wrong format", body) + return body +} + +// POST /keys/{name}/recover Recover a account from a seed +func doRecoverKey(t *testing.T, port, recoverName, recoverPassword, seed string) { + jsonStr := []byte(fmt.Sprintf(`{"password":"%s", "seed":"%s"}`, recoverPassword, seed)) + res, body := Request(t, port, "POST", fmt.Sprintf("/keys/%s/recover", recoverName), jsonStr) + + require.Equal(t, http.StatusOK, res.StatusCode, body) + var resp keys.KeyOutput + err := codec.Cdc.UnmarshalJSON([]byte(body), &resp) + require.Nil(t, err, body) + + addr1Bech32 := resp.Address + _, err = sdk.AccAddressFromBech32(addr1Bech32) + require.NoError(t, err, "Failed to return a correct bech32 address") +} + +// GET /keys/{name} Get a certain locally stored account +func getKey(t *testing.T, port, name string) keys.KeyOutput { + res, body := Request(t, port, "GET", fmt.Sprintf("/keys/%s", name), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var resp keys.KeyOutput + err := cdc.UnmarshalJSON([]byte(body), &resp) + require.Nil(t, err) + return resp +} + +// PUT /keys/{name} Update the password for this account in the KMS +func updateKey(t *testing.T, port, name, oldPassword, newPassword string, fail bool) { + kr := updateKeyReq{oldPassword, newPassword} + req, err := cdc.MarshalJSON(kr) + require.NoError(t, err) + keyEndpoint := fmt.Sprintf("/keys/%s", name) + res, body := Request(t, port, "PUT", keyEndpoint, req) + if fail { + require.Equal(t, http.StatusUnauthorized, res.StatusCode, body) + return + } + require.Equal(t, http.StatusOK, res.StatusCode, body) +} + +type updateKeyReq struct { + OldPassword string `json:"old_password"` + NewPassword string `json:"new_password"` +} + +// DELETE /keys/{name} Remove an account +func deleteKey(t *testing.T, port, name, password string) { + dk := deleteKeyReq{password} + req, err := cdc.MarshalJSON(dk) + require.NoError(t, err) + keyEndpoint := fmt.Sprintf("/keys/%s", name) + res, body := Request(t, port, "DELETE", keyEndpoint, req) + require.Equal(t, http.StatusOK, res.StatusCode, body) +} + +type deleteKeyReq struct { + Password string `json:"password"` +} + +// GET /auth/accounts/{address} Get the account information on blockchain +func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account { + res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", addr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var acc auth.Account + err := cdc.UnmarshalJSON([]byte(body), &acc) + require.Nil(t, err) + return acc +} + +// ---------------------------------------------------------------------- +// ICS 20 - Tokens +// ---------------------------------------------------------------------- + +// POST /tx/sign Sign a Tx +func doSign(t *testing.T, port, name, password, chainID string, accnum, sequence uint64, msg auth.StdTx) auth.StdTx { + var signedMsg auth.StdTx + payload := authrest.SignBody{ + Tx: msg, + LocalAccountName: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + } + json, err := cdc.MarshalJSON(payload) + require.Nil(t, err) + res, body := Request(t, port, "POST", "/tx/sign", json) + require.Equal(t, http.StatusOK, res.StatusCode, body) + require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg)) + return signedMsg +} + +// POST /tx/broadcast Send a signed Tx +func doBroadcast(t *testing.T, port string, msg auth.StdTx) ctypes.ResultBroadcastTxCommit { + tx := broadcastReq{Tx: msg, Return: "block"} + req, err := cdc.MarshalJSON(tx) + require.Nil(t, err) + res, body := Request(t, port, "POST", "/tx/broadcast", req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var resultTx ctypes.ResultBroadcastTxCommit + require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx)) + return resultTx +} + +type broadcastReq struct { + Tx auth.StdTx `json:"tx"` + Return string `json:"return"` +} + +// GET /bank/balances/{address} Get the account balances + +// POST /bank/accounts/{address}/transfers Send coins (build -> sign -> send) +func doTransfer(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) { + res, body, receiveAddr := doTransferWithGas(t, port, seed, name, password, addr, "", 0, false, false) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err := cdc.UnmarshalJSON([]byte(body), &resultTx) + require.Nil(t, err) + + return receiveAddr, resultTx +} + +func doTransferWithGas(t *testing.T, port, seed, name, password string, addr sdk.AccAddress, gas string, + gasAdjustment float64, simulate, generateOnly bool) ( + res *http.Response, body string, receiveAddr sdk.AccAddress) { + + // create receive address + kb := client.MockKeyBase() + receiveInfo, _, err := kb.CreateMnemonic("receive_address", cryptoKeys.English, gapp.DefaultKeyPass, cryptoKeys.SigningAlgo("secp256k1")) + require.Nil(t, err) + receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address()) + + acc := getAccount(t, port, addr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + chainID := viper.GetString(client.FlagChainID) + + sr := sendReq{ + Amount: sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 1)}, + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + Simulate: simulate, + GenerateOnly: generateOnly, + }, + } + + if len(gas) != 0 { + sr.BaseReq.Gas = gas + } + + if gasAdjustment > 0 { + sr.BaseReq.GasAdjustment = fmt.Sprintf("%f", gasAdjustment) + } + + req, err := cdc.MarshalJSON(sr) + require.NoError(t, err) + + res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req) + return +} + +type sendReq struct { + Amount sdk.Coins `json:"amount"` + BaseReq utils.BaseReq `json:"base_req"` +} + +// ---------------------------------------------------------------------- +// ICS 21 - Stake +// ---------------------------------------------------------------------- + +// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation +func doDelegate(t *testing.T, port, name, password string, + delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { + + acc := getAccount(t, port, delAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + chainID := viper.GetString(client.FlagChainID) + ed := msgDelegationsInput{ + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + DelegatorAddr: delAddr, + ValidatorAddr: valAddr, + Delegation: sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, amount), + } + req, err := cdc.MarshalJSON(ed) + require.NoError(t, err) + res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr.String()), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + return results +} + +type msgDelegationsInput struct { + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 + Delegation sdk.Coin `json:"delegation"` +} + +// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation +func doBeginUnbonding(t *testing.T, port, name, password string, + delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { + + acc := getAccount(t, port, delAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + chainID := viper.GetString(client.FlagChainID) + ed := msgBeginUnbondingInput{ + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + DelegatorAddr: delAddr, + ValidatorAddr: valAddr, + SharesAmount: sdk.NewDec(amount), + } + req, err := cdc.MarshalJSON(ed) + require.NoError(t, err) + + res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations", delAddr), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results +} + +type msgBeginUnbondingInput struct { + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 + SharesAmount sdk.Dec `json:"shares"` +} + +// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation +func doBeginRedelegation(t *testing.T, port, name, password string, + delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { + + acc := getAccount(t, port, delAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + + chainID := viper.GetString(client.FlagChainID) + ed := msgBeginRedelegateInput{ + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + DelegatorAddr: delAddr, + ValidatorSrcAddr: valSrcAddr, + ValidatorDstAddr: valDstAddr, + SharesAmount: sdk.NewDec(amount), + } + req, err := cdc.MarshalJSON(ed) + require.NoError(t, err) + + res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/redelegations", delAddr), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results +} + +type msgBeginRedelegateInput struct { + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // in bech32 + ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"` // in bech32 + SharesAmount sdk.Dec `json:"shares"` +} + +// GET /stake/delegators/{delegatorAddr}/delegations Get all delegations from a delegator +func getDelegatorDelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Delegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var dels []stake.Delegation + + err := cdc.UnmarshalJSON([]byte(body), &dels) + require.Nil(t, err) + + return dels +} + +// GET /stake/delegators/{delegatorAddr}/unbonding_delegations Get all unbonding delegations from a delegator +func getDelegatorUnbondingDelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.UnbondingDelegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations", delegatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var ubds []stake.UnbondingDelegation + + err := cdc.UnmarshalJSON([]byte(body), &ubds) + require.Nil(t, err) + + return ubds +} + +// GET /stake/delegators/{delegatorAddr}/redelegations Get all redelegations from a delegator +func getDelegatorRedelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Redelegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/redelegations", delegatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var reds []stake.Redelegation + + err := cdc.UnmarshalJSON([]byte(body), &reds) + require.Nil(t, err) + + return reds +} + +// GET /stake/delegators/{delegatorAddr}/validators Query all validators that a delegator is bonded to +func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Validator { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators", delegatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var bondedValidators []stake.Validator + + err := cdc.UnmarshalJSON([]byte(body), &bondedValidators) + require.Nil(t, err) + + return bondedValidators +} + +// GET /stake/delegators/{delegatorAddr}/validators/{validatorAddr} Query a validator that a delegator is bonded to +func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Validator { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var bondedValidator stake.Validator + err := cdc.UnmarshalJSON([]byte(body), &bondedValidator) + require.Nil(t, err) + + return bondedValidator +} + +// GET /stake/delegators/{delegatorAddr}/txs Get all staking txs (i.e msgs) from a delegator +func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info { + var res *http.Response + var body string + + if len(query) > 0 { + res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil) + } else { + res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil) + } + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var txs []tx.Info + + err := cdc.UnmarshalJSON([]byte(body), &txs) + require.Nil(t, err) + + return txs +} + +// GET /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} Query the current delegation between a delegator and a validator +func getDelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Delegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var bond stake.Delegation + err := cdc.UnmarshalJSON([]byte(body), &bond) + require.Nil(t, err) + + return bond +} + +// GET /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} Query all unbonding delegations between a delegator and a validator +func getUndelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.UnbondingDelegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var unbond stake.UnbondingDelegation + err := cdc.UnmarshalJSON([]byte(body), &unbond) + require.Nil(t, err) + + return unbond +} + +// GET /stake/validators Get all validator candidates +func getValidators(t *testing.T, port string) []stake.Validator { + res, body := Request(t, port, "GET", "/stake/validators", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var validators []stake.Validator + err := cdc.UnmarshalJSON([]byte(body), &validators) + require.Nil(t, err) + + return validators +} + +// GET /stake/validators/{validatorAddr} Query the information from a single validator +func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake.Validator { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var validator stake.Validator + err := cdc.UnmarshalJSON([]byte(body), &validator) + require.Nil(t, err) + + return validator +} + +// GET /stake/validators/{validatorAddr}/delegations Get all delegations from a validator +func getValidatorDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Delegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/delegations", validatorAddr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var delegations []stake.Delegation + err := cdc.UnmarshalJSON([]byte(body), &delegations) + require.Nil(t, err) + + return delegations +} + +// GET /stake/validators/{validatorAddr}/unbonding_delegations Get all unbonding delegations from a validator +func getValidatorUnbondingDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.UnbondingDelegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/unbonding_delegations", validatorAddr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var ubds []stake.UnbondingDelegation + err := cdc.UnmarshalJSON([]byte(body), &ubds) + require.Nil(t, err) + + return ubds +} + +// GET /stake/validators/{validatorAddr}/redelegations Get all outgoing redelegations from a validator +func getValidatorRedelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Redelegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/redelegations", validatorAddr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var reds []stake.Redelegation + err := cdc.UnmarshalJSON([]byte(body), &reds) + require.Nil(t, err) + + return reds +} + +// GET /stake/pool Get the current state of the staking pool +func getStakePool(t *testing.T, port string) stake.Pool { + res, body := Request(t, port, "GET", "/stake/pool", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + require.NotNil(t, body) + var pool stake.Pool + err := cdc.UnmarshalJSON([]byte(body), &pool) + require.Nil(t, err) + return pool +} + +// GET /stake/parameters Get the current staking parameter values +func getStakeParams(t *testing.T, port string) stake.Params { + res, body := Request(t, port, "GET", "/stake/parameters", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var params stake.Params + err := cdc.UnmarshalJSON([]byte(body), ¶ms) + require.Nil(t, err) + return params +} + +// ---------------------------------------------------------------------- +// ICS 22 - Gov +// ---------------------------------------------------------------------- +// POST /gov/proposals Submit a proposal +func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { + + acc := getAccount(t, port, proposerAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + + chainID := viper.GetString(client.FlagChainID) + pr := postProposalReq{ + Title: "Test", + Description: "test", + ProposalType: "Text", + Proposer: proposerAddr, + InitialDeposit: sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(amount))}, + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + } + + req, err := cdc.MarshalJSON(pr) + require.NoError(t, err) + + // submitproposal + res, body := Request(t, port, "POST", "/gov/proposals", req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results +} + +type postProposalReq struct { + BaseReq utils.BaseReq `json:"base_req"` + Title string `json:"title"` // Title of the proposal + Description string `json:"description"` // Description of the proposal + ProposalType string `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal} + Proposer sdk.AccAddress `json:"proposer"` // Address of the proposer + InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit +} + +// GET /gov/proposals Query proposals +func getProposalsAll(t *testing.T, port string) []gov.Proposal { + res, body := Request(t, port, "GET", "/gov/proposals", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var proposals []gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposals) + require.Nil(t, err) + return proposals +} + +// GET /gov/proposals?depositor=%s Query proposals +func getProposalsFilterDepositor(t *testing.T, port string, depositorAddr sdk.AccAddress) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s", depositorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var proposals []gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposals) + require.Nil(t, err) + return proposals +} + +// GET /gov/proposals?voter=%s Query proposals +func getProposalsFilterVoter(t *testing.T, port string, voterAddr sdk.AccAddress) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?voter=%s", voterAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var proposals []gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposals) + require.Nil(t, err) + return proposals +} + +// GET /gov/proposals?depositor=%s&voter=%s Query proposals +func getProposalsFilterVoterDepositor(t *testing.T, port string, voterAddr, depositorAddr sdk.AccAddress) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s&voter=%s", depositorAddr, voterAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var proposals []gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposals) + require.Nil(t, err) + return proposals +} + +// GET /gov/proposals?status=%s Query proposals +func getProposalsFilterStatus(t *testing.T, port string, status gov.ProposalStatus) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?status=%s", status), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var proposals []gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposals) + require.Nil(t, err) + return proposals +} + +// POST /gov/proposals/{proposalId}/deposits Deposit tokens to a proposal +func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) { + + acc := getAccount(t, port, proposerAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + + chainID := viper.GetString(client.FlagChainID) + dr := depositReq{ + Depositor: proposerAddr, + Amount: sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(amount))}, + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + } + + req, err := cdc.MarshalJSON(dr) + require.NoError(t, err) + + res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results +} + +type depositReq struct { + BaseReq utils.BaseReq `json:"base_req"` + Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor + Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit +} + +// GET /gov/proposals/{proposalId}/deposits Query deposits +func getDeposits(t *testing.T, port string, proposalID uint64) []gov.Deposit { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var deposits []gov.Deposit + err := cdc.UnmarshalJSON([]byte(body), &deposits) + require.Nil(t, err) + return deposits +} + +// GET /gov/proposals/{proposalId}/tally Get a proposal's tally result at the current time +func getTally(t *testing.T, port string, proposalID uint64) gov.TallyResult { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/tally", proposalID), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var tally gov.TallyResult + err := cdc.UnmarshalJSON([]byte(body), &tally) + require.Nil(t, err) + return tally +} + +// POST /gov/proposals/{proposalId}/votes Vote a proposal +func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64) (resultTx ctypes.ResultBroadcastTxCommit) { + // get the account to get the sequence + acc := getAccount(t, port, proposerAddr) + accnum := acc.GetAccountNumber() + sequence := acc.GetSequence() + + chainID := viper.GetString(client.FlagChainID) + vr := voteReq{ + Voter: proposerAddr, + Option: "Yes", + BaseReq: utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: accnum, + Sequence: sequence, + }, + } + + req, err := cdc.MarshalJSON(vr) + require.NoError(t, err) + + res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results +} + +type voteReq struct { + BaseReq utils.BaseReq `json:"base_req"` + Voter sdk.AccAddress `json:"voter"` // address of the voter + Option string `json:"option"` // option from OptionSet chosen by the voter +} + +// GET /gov/proposals/{proposalId}/votes Query voters +func getVotes(t *testing.T, port string, proposalID uint64) []gov.Vote { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var votes []gov.Vote + err := cdc.UnmarshalJSON([]byte(body), &votes) + require.Nil(t, err) + return votes +} + +// GET /gov/proposals/{proposalId} Query a proposal +func getProposal(t *testing.T, port string, proposalID uint64) gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d", proposalID), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var proposal gov.Proposal + err := cdc.UnmarshalJSON([]byte(body), &proposal) + require.Nil(t, err) + return proposal +} + +// GET /gov/proposals/{proposalId}/deposits/{depositor} Query deposit +func getDeposit(t *testing.T, port string, proposalID uint64, depositorAddr sdk.AccAddress) gov.Deposit { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits/%s", proposalID, depositorAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var deposit gov.Deposit + err := cdc.UnmarshalJSON([]byte(body), &deposit) + require.Nil(t, err) + return deposit +} + +// GET /gov/proposals/{proposalId}/votes/{voter} Query vote +func getVote(t *testing.T, port string, proposalID uint64, voterAddr sdk.AccAddress) gov.Vote { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes/%s", proposalID, voterAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var vote gov.Vote + err := cdc.UnmarshalJSON([]byte(body), &vote) + require.Nil(t, err) + return vote +} + +// GET /gov/parameters/deposit Query governance deposit parameters +func getDepositParam(t *testing.T, port string) gov.DepositParams { + res, body := Request(t, port, "GET", "/gov/parameters/deposit", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var depositParams gov.DepositParams + err := cdc.UnmarshalJSON([]byte(body), &depositParams) + require.Nil(t, err) + return depositParams +} + +// GET /gov/parameters/tallying Query governance tally parameters +func getTallyingParam(t *testing.T, port string) gov.TallyParams { + res, body := Request(t, port, "GET", "/gov/parameters/tallying", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var tallyParams gov.TallyParams + err := cdc.UnmarshalJSON([]byte(body), &tallyParams) + require.Nil(t, err) + return tallyParams +} + +// GET /gov/parameters/voting Query governance voting parameters +func getVotingParam(t *testing.T, port string) gov.VotingParams { + res, body := Request(t, port, "GET", "/gov/parameters/voting", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var votingParams gov.VotingParams + err := cdc.UnmarshalJSON([]byte(body), &votingParams) + require.Nil(t, err) + return votingParams +} + +// ---------------------------------------------------------------------- +// ICS 23 - Slashing +// ---------------------------------------------------------------------- +// GET /slashing/validators/{validatorPubKey}/signing_info Get sign info of given validator +func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo { + res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/validators/%s/signing_info", validatorPubKey), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var signingInfo slashing.ValidatorSigningInfo + err := cdc.UnmarshalJSON([]byte(body), &signingInfo) + require.Nil(t, err) + + return signingInfo +} + +// TODO: Test this functionality, it is not currently in any of the tests +// POST /slashing/validators/{validatorAddr}/unjail Unjail a jailed validator +func doUnjail(t *testing.T, port, seed, name, password string, + valAddr sdk.ValAddress) (resultTx ctypes.ResultBroadcastTxCommit) { + chainID := viper.GetString(client.FlagChainID) + + ur := unjailReq{utils.BaseReq{ + Name: name, + Password: password, + ChainID: chainID, + AccountNumber: 1, + Sequence: 1, + }} + req, err := cdc.MarshalJSON(ur) + require.NoError(t, err) + res, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), req) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var results []ctypes.ResultBroadcastTxCommit + err = cdc.UnmarshalJSON([]byte(body), &results) + require.Nil(t, err) + + return results[0] +} + +type unjailReq struct { + BaseReq utils.BaseReq `json:"base_req"` +} diff --git a/client/rpc/block.go b/client/rpc/block.go index b2db545db..ee77fb5c1 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -8,11 +8,12 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/gorilla/mux" "github.com/spf13/cobra" "github.com/spf13/viper" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" + + "github.com/cosmos/cosmos-sdk/client/utils" ) //BlockCommand returns the verified block data for a given heights diff --git a/client/rpc/root.go b/client/rpc/root.go index 7bdcd8cd8..c8a98bc44 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -5,9 +5,10 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/spf13/viper" ) const ( diff --git a/client/rpc/status.go b/client/rpc/status.go index 0f81fc9c6..86bb1ef31 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -7,11 +7,12 @@ import ( "github.com/spf13/cobra" + "github.com/spf13/viper" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" - "github.com/spf13/viper" - ctypes "github.com/tendermint/tendermint/rpc/core/types" ) // StatusCommand returns the status of the network diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 6ec7ba615..9d401f69c 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -9,12 +9,13 @@ import ( "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/spf13/viper" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/viper" - tmtypes "github.com/tendermint/tendermint/types" ) // TODO these next two functions feel kinda hacky based on their placement diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index 8346e1538..4080b68ec 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -3,10 +3,11 @@ package tx import ( "net/http" + "io/ioutil" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" - "io/ioutil" ) const ( diff --git a/client/tx/query.go b/client/tx/query.go index 3bbbf9a13..945701224 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -12,13 +12,14 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/spf13/viper" ) // QueryTxCmd implements the default command for a tx query. diff --git a/client/utils/rest.go b/client/utils/rest.go index c0a8c3c77..5917455ee 100644 --- a/client/utils/rest.go +++ b/client/utils/rest.go @@ -4,7 +4,6 @@ import ( "fmt" "io/ioutil" "net/http" - "net/url" "strconv" "strings" @@ -17,11 +16,6 @@ import ( authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" ) -const ( - queryArgDryRun = "simulate" - queryArgGenerateOnly = "generate_only" -) - //---------------------------------------- // Basic HTTP utilities @@ -39,18 +33,6 @@ func WriteSimulationResponse(w http.ResponseWriter, gas uint64) { w.Write([]byte(fmt.Sprintf(`{"gas_estimate":%v}`, gas))) } -// HasDryRunArg returns true if the request's URL query contains the dry run -// argument and its value is set to "true". -func HasDryRunArg(r *http.Request) bool { - return urlQueryHasArg(r.URL, queryArgDryRun) -} - -// HasGenerateOnlyArg returns whether a URL's query "generate-only" parameter -// is set to "true". -func HasGenerateOnlyArg(r *http.Request) bool { - return urlQueryHasArg(r.URL, queryArgGenerateOnly) -} - // ParseInt64OrReturnBadRequest converts s to a int64 value. func ParseInt64OrReturnBadRequest(w http.ResponseWriter, s string) (n int64, ok bool) { var err error @@ -113,8 +95,6 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, txBldr authtxb.TxBuilder, return } -func urlQueryHasArg(url *url.URL, arg string) bool { return url.Query().Get(arg) == "true" } - //---------------------------------------- // Building / Sending utilities @@ -128,6 +108,8 @@ type BaseReq struct { Sequence uint64 `json:"sequence"` Gas string `json:"gas"` GasAdjustment string `json:"gas_adjustment"` + GenerateOnly bool `json:"generate_only"` + Simulate bool `json:"simulate"` } // Sanitize performs basic sanitization on a BaseReq object. @@ -140,6 +122,8 @@ func (br BaseReq) Sanitize() BaseReq { GasAdjustment: strings.TrimSpace(br.GasAdjustment), AccountNumber: br.AccountNumber, Sequence: br.Sequence, + GenerateOnly: br.GenerateOnly, + Simulate: br.Simulate, } } @@ -175,21 +159,21 @@ func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req i // ValidateBasic performs basic validation of a BaseReq. If custom validation // logic is needed, the implementing request handler should perform those // checks manually. -func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { - switch { - case len(br.Name) == 0: +func (br BaseReq) ValidateBasic(w http.ResponseWriter, cliCtx context.CLIContext) bool { + if !cliCtx.GenerateOnly && !cliCtx.Simulate { + switch { + case len(br.Password) == 0: + WriteErrorResponse(w, http.StatusUnauthorized, "password required but not specified") + return false + case len(br.ChainID) == 0: + WriteErrorResponse(w, http.StatusUnauthorized, "chain-id required but not specified") + return false + } + } + if len(br.Name) == 0 { WriteErrorResponse(w, http.StatusUnauthorized, "name required but not specified") return false - - case len(br.Password) == 0: - WriteErrorResponse(w, http.StatusUnauthorized, "password required but not specified") - return false - - case len(br.ChainID) == 0: - WriteErrorResponse(w, http.StatusUnauthorized, "chainID required but not specified") - return false } - return true } @@ -223,14 +207,14 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c Sequence: baseReq.Sequence, } - if HasDryRunArg(r) || txBldr.SimulateGas { + if baseReq.Simulate || txBldr.SimulateGas { newBldr, err := EnrichCtxWithGas(txBldr, cliCtx, baseReq.Name, msgs) if err != nil { WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - if HasDryRunArg(r) { + if baseReq.Simulate { WriteSimulationResponse(w, newBldr.Gas) return } @@ -238,7 +222,7 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c txBldr = newBldr } - if HasGenerateOnlyArg(r) { + if baseReq.GenerateOnly { WriteGenerateStdTxResponse(w, txBldr, msgs) return } diff --git a/client/utils/utils.go b/client/utils/utils.go index 2d506e462..6fde3ce6b 100644 --- a/client/utils/utils.go +++ b/client/utils/utils.go @@ -6,13 +6,14 @@ import ( "io" "os" + "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/keys" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" - "github.com/tendermint/go-amino" - "github.com/tendermint/tendermint/libs/common" ) // CompleteAndBroadcastTxCli implements a utility function that facilitates @@ -33,14 +34,14 @@ func CompleteAndBroadcastTxCli(txBldr authtxb.TxBuilder, cliCtx context.CLIConte return err } - if txBldr.SimulateGas || cliCtx.DryRun { + if txBldr.SimulateGas || cliCtx.Simulate { txBldr, err = EnrichCtxWithGas(txBldr, cliCtx, name, msgs) if err != nil { return err } fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas) } - if cliCtx.DryRun { + if cliCtx.Simulate { return nil } diff --git a/client/utils/utils_test.go b/client/utils/utils_test.go index b22a50806..23c665239 100644 --- a/client/utils/utils_test.go +++ b/client/utils/utils_test.go @@ -4,10 +4,11 @@ import ( "errors" "testing" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/tendermint/tendermint/libs/common" + + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestParseQueryResponse(t *testing.T) { diff --git a/cmd/cosmos-sdk-cli/cmd/init.go b/cmd/cosmos-sdk-cli/cmd/init.go index fcf30b972..f8cf88b88 100644 --- a/cmd/cosmos-sdk-cli/cmd/init.go +++ b/cmd/cosmos-sdk-cli/cmd/init.go @@ -9,9 +9,10 @@ import ( "path/filepath" - "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" tmversion "github.com/tendermint/tendermint/version" + + "github.com/cosmos/cosmos-sdk/version" ) var remoteBasecoinPath = "github.com/cosmos/cosmos-sdk/docs/examples/basecoin" diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 270fe52ec..d97d25f0a 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -6,6 +6,11 @@ import ( "os" "sort" + abci "github.com/tendermint/tendermint/abci/types" + cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" + bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,10 +22,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" - abci "github.com/tendermint/tendermint/abci/types" - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" ) const ( diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index e356d6d6d..238f22966 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -4,6 +4,10 @@ import ( "os" "testing" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/auth" distr "github.com/cosmos/cosmos-sdk/x/distribution" @@ -11,9 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" abci "github.com/tendermint/tendermint/abci/types" ) diff --git a/cmd/gaia/app/benchmarks/txsize_test.go b/cmd/gaia/app/benchmarks/txsize_test.go index a401c16ca..d9862f22c 100644 --- a/cmd/gaia/app/benchmarks/txsize_test.go +++ b/cmd/gaia/app/benchmarks/txsize_test.go @@ -3,11 +3,12 @@ package app import ( "fmt" + "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/tendermint/tendermint/crypto/secp256k1" ) // This will fail half the time with the second output being 173 diff --git a/cmd/gaia/app/export.go b/cmd/gaia/app/export.go index a2aa42087..2b51c444b 100644 --- a/cmd/gaia/app/export.go +++ b/cmd/gaia/app/export.go @@ -4,6 +4,9 @@ import ( "encoding/json" "fmt" + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -12,8 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/slashing" stake "github.com/cosmos/cosmos-sdk/x/stake" - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" ) // export the state of gaia for a genesis file diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index ee3ecfcd6..9c92f60ba 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -10,6 +10,8 @@ import ( "sort" "strings" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -19,7 +21,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - tmtypes "github.com/tendermint/tendermint/types" ) var ( diff --git a/cmd/gaia/app/genesis_test.go b/cmd/gaia/app/genesis_test.go index 1b1c19646..425962fa3 100644 --- a/cmd/gaia/app/genesis_test.go +++ b/cmd/gaia/app/genesis_test.go @@ -7,13 +7,14 @@ import ( "github.com/tendermint/tendermint/crypto/secp256k1" tmtypes "github.com/tendermint/tendermint/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/stake" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" ) var ( diff --git a/cmd/gaia/app/invariants.go b/cmd/gaia/app/invariants.go index 4a60a41ae..4582457fc 100644 --- a/cmd/gaia/app/invariants.go +++ b/cmd/gaia/app/invariants.go @@ -4,12 +4,13 @@ import ( "fmt" "time" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation" "github.com/cosmos/cosmos-sdk/x/mock/simulation" stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" - abci "github.com/tendermint/tendermint/abci/types" ) func (app *GaiaApp) runtimeInvariants() []simulation.Invariant { diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index bf03f9a10..b4504bdf8 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -76,14 +76,15 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage { } // Random genesis states + vp := time.Duration(r.Intn(2*172800)) * time.Second govGenesis := gov.GenesisState{ StartingProposalID: uint64(r.Intn(100)), DepositParams: gov.DepositParams{ MinDeposit: sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, int64(r.Intn(1e3)))}, - MaxDepositPeriod: time.Duration(r.Intn(2*172800)) * time.Second, + MaxDepositPeriod: vp, }, VotingParams: gov.VotingParams{ - VotingPeriod: time.Duration(r.Intn(2*172800)) * time.Second, + VotingPeriod: vp, }, TallyParams: gov.TallyParams{ Threshold: sdk.NewDecWithPrec(5, 1), diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index f7d3b2d83..845edc757 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -645,6 +645,37 @@ trust_node = true cleanupDirs(gaiadHome, gaiacliHome) } +func TestGaiadCollectGentxs(t *testing.T) { + t.Parallel() + // Initialise temporary directories + gaiadHome, gaiacliHome := getTestingHomeDirs(t.Name()) + gentxDir, err := ioutil.TempDir("", "") + gentxDoc := filepath.Join(gentxDir, "gentx.json") + require.NoError(t, err) + + tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "") + os.RemoveAll(filepath.Join(gaiadHome, "config", "gentx")) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass) + executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass) + executeWriteCheckErr(t, fmt.Sprintf("gaiacli keys add --home=%s foo", gaiacliHome), app.DefaultKeyPass) + executeWriteCheckErr(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass) + executeWriteCheckErr(t, fmt.Sprintf("gaiacli config --home=%s output json", gaiacliHome)) + fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --home=%s", gaiacliHome)) + + // Run init + _ = executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome)) + // Add account to genesis.json + executeWriteCheckErr(t, fmt.Sprintf( + "gaiad add-genesis-account %s 150%s,1000fooToken --home=%s", fooAddr, stakeTypes.DefaultBondDenom, gaiadHome)) + executeWrite(t, fmt.Sprintf("cat %s%sconfig%sgenesis.json", gaiadHome, string(os.PathSeparator), string(os.PathSeparator))) + // Write gentx file + executeWriteCheckErr(t, fmt.Sprintf( + "gaiad gentx --name=foo --home=%s --home-client=%s --output-document=%s", gaiadHome, gaiacliHome, gentxDoc), app.DefaultKeyPass) + // Collect gentxs from a custom directory + executeWriteCheckErr(t, fmt.Sprintf("gaiad collect-gentxs --home=%s --gentx-dir=%s", gaiadHome, gentxDir), app.DefaultKeyPass) + cleanupDirs(gaiadHome, gaiacliHome, gentxDir) +} + //___________________________________________________________________________________ // helper methods diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go index 5117d0aa1..59e324966 100644 --- a/cmd/gaia/cmd/gaiadebug/main.go +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -10,12 +10,13 @@ import ( "strconv" "strings" - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/spf13/cobra" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) func init() { diff --git a/cmd/gaia/init/collect.go b/cmd/gaia/init/collect.go index cdfc1688c..e630d494c 100644 --- a/cmd/gaia/init/collect.go +++ b/cmd/gaia/init/collect.go @@ -4,17 +4,22 @@ import ( "encoding/json" "path/filepath" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/spf13/cobra" "github.com/spf13/viper" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +const ( + flagGenTxDir = "gentx-dir" ) type initConfig struct { @@ -34,7 +39,6 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { config := ctx.Config config.SetRoot(viper.GetString(cli.HomeFlag)) name := viper.GetString(client.FlagName) - nodeID, valPubKey, err := InitializeNodeValidatorFiles(config) if err != nil { return err @@ -45,19 +49,13 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { return err } - toPrint := printInfo{ - Moniker: config.Moniker, - ChainID: genDoc.ChainID, - NodeID: nodeID, + genTxsDir := viper.GetString(flagGenTxDir) + if genTxsDir == "" { + genTxsDir = filepath.Join(config.RootDir, "config", "gentx") } - initCfg := initConfig{ - ChainID: genDoc.ChainID, - GenTxsDir: filepath.Join(config.RootDir, "config", "gentx"), - Name: name, - NodeID: nodeID, - ValPubKey: valPubKey, - } + toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage("")) + initCfg := newInitConfig(genDoc.ChainID, genTxsDir, name, nodeID, valPubKey) appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc) if err != nil { @@ -72,6 +70,9 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { } cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory") + cmd.Flags().String(flagGenTxDir, "", + "override default \"gentx\" directory from which collect and execute "+ + "genesis transactions; default [--home]/config/gentx/") return cmd } @@ -116,3 +117,27 @@ func genAppStateFromConfig( err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState) return } + +func newInitConfig(chainID, genTxsDir, name, nodeID string, + valPubKey crypto.PubKey) initConfig { + + return initConfig{ + ChainID: chainID, + GenTxsDir: genTxsDir, + Name: name, + NodeID: nodeID, + ValPubKey: valPubKey, + } +} + +func newPrintInfo(moniker, chainID, nodeID, genTxsDir string, + appMessage json.RawMessage) printInfo { + + return printInfo{ + Moniker: moniker, + ChainID: chainID, + NodeID: nodeID, + GenTxsDir: genTxsDir, + AppMessage: appMessage, + } +} diff --git a/cmd/gaia/init/genesis_accts.go b/cmd/gaia/init/genesis_accts.go index 04c1f6283..4f5043877 100644 --- a/cmd/gaia/init/genesis_accts.go +++ b/cmd/gaia/init/genesis_accts.go @@ -4,15 +4,16 @@ import ( "encoding/json" "fmt" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/tendermint/libs/cli" + "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/tendermint/tendermint/libs/cli" - "github.com/tendermint/tendermint/libs/common" ) // AddGenesisAccountCmd returns add-genesis-account cobra Command diff --git a/cmd/gaia/init/genesis_accts_test.go b/cmd/gaia/init/genesis_accts_test.go index 49634a90c..42a36b263 100644 --- a/cmd/gaia/init/genesis_accts_test.go +++ b/cmd/gaia/init/genesis_accts_test.go @@ -1,9 +1,10 @@ package init import ( + "testing" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" - "testing" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" diff --git a/cmd/gaia/init/gentx.go b/cmd/gaia/init/gentx.go index 0a4eb8034..9f985762a 100644 --- a/cmd/gaia/init/gentx.go +++ b/cmd/gaia/init/gentx.go @@ -11,6 +11,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" + tmcli "github.com/tendermint/tendermint/libs/cli" + "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/keys" @@ -23,10 +28,6 @@ import ( authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/stake/client/cli" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto" - tmcli "github.com/tendermint/tendermint/libs/cli" - "github.com/tendermint/tendermint/libs/common" ) const ( @@ -136,9 +137,12 @@ following delegation and commission default parameters: } // Fetch output file name - outputDocument, err := makeOutputFilepath(config.RootDir, nodeID) - if err != nil { - return err + outputDocument := viper.GetString(client.FlagOutputDocument) + if outputDocument == "" { + outputDocument, err = makeOutputFilepath(config.RootDir, nodeID) + if err != nil { + return err + } } if err := writeSignedGenTx(cdc, outputDocument, signedTx); err != nil { @@ -153,6 +157,8 @@ following delegation and commission default parameters: cmd.Flags().String(tmcli.HomeFlag, app.DefaultNodeHome, "node's home directory") cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory") cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx") + cmd.Flags().String(client.FlagOutputDocument, "", + "write the genesis transaction JSON document to the given file instead of the default location") cmd.Flags().AddFlagSet(cli.FsCommissionCreate) cmd.Flags().AddFlagSet(cli.FsAmount) cmd.Flags().AddFlagSet(cli.FsPk) diff --git a/cmd/gaia/init/init.go b/cmd/gaia/init/init.go index 19179233a..922cfbafa 100644 --- a/cmd/gaia/init/init.go +++ b/cmd/gaia/init/init.go @@ -6,15 +6,16 @@ import ( "os" "path/filepath" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/server" "github.com/spf13/cobra" "github.com/spf13/viper" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/common" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" ) const ( @@ -27,6 +28,7 @@ type printInfo struct { Moniker string `json:"moniker"` ChainID string `json:"chain_id"` NodeID string `json:"node_id"` + GenTxsDir string `json:"gentxs_dir"` AppMessage json.RawMessage `json:"app_message"` } @@ -76,12 +78,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { return err } - toPrint := printInfo{ - ChainID: chainID, - Moniker: config.Moniker, - NodeID: nodeID, - AppMessage: appState, - } + toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState) cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) diff --git a/cmd/gaia/init/init_test.go b/cmd/gaia/init/init_test.go index 1eeba66ae..faf324e6c 100644 --- a/cmd/gaia/init/init_test.go +++ b/cmd/gaia/init/init_test.go @@ -8,17 +8,19 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/tendermint/tendermint/libs/cli" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/server/mock" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/stretchr/testify/require" abciServer "github.com/tendermint/tendermint/abci/server" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/libs/log" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/server/mock" + "github.com/spf13/viper" ) diff --git a/cmd/gaia/init/testnet.go b/cmd/gaia/init/testnet.go index 73a7cea14..10b0b8265 100644 --- a/cmd/gaia/init/testnet.go +++ b/cmd/gaia/init/testnet.go @@ -16,7 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/cosmos/cosmos-sdk/server" "github.com/spf13/cobra" "github.com/spf13/viper" cfg "github.com/tendermint/tendermint/config" @@ -24,6 +23,8 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/types" tmtime "github.com/tendermint/tendermint/types/time" + + "github.com/cosmos/cosmos-sdk/server" ) var ( @@ -278,13 +279,7 @@ func collectGenFiles( config.SetRoot(nodeDir) nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - initCfg := initConfig{ - ChainID: chainID, - GenTxsDir: gentxsDir, - Name: moniker, - NodeID: nodeID, - ValPubKey: valPubKey, - } + initCfg := newInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey) genDoc, err := loadGenesisDoc(cdc, config.GenesisFile()) if err != nil { diff --git a/cmd/gaia/init/utils.go b/cmd/gaia/init/utils.go index 58edc9b2a..14c625d7f 100644 --- a/cmd/gaia/init/utils.go +++ b/cmd/gaia/init/utils.go @@ -6,8 +6,6 @@ import ( "io/ioutil" "time" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/codec" amino "github.com/tendermint/go-amino" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" @@ -15,6 +13,9 @@ import ( "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/codec" ) // ExportGenesisFile creates and writes the genesis configuration to disk. An diff --git a/crypto/keys/codec.go b/crypto/keys/codec.go index 80a13539a..f6c1a013d 100644 --- a/crypto/keys/codec.go +++ b/crypto/keys/codec.go @@ -1,9 +1,10 @@ package keys import ( - ccrypto "github.com/cosmos/cosmos-sdk/crypto" amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto/encoding/amino" + + ccrypto "github.com/cosmos/cosmos-sdk/crypto" ) var cdc = amino.NewCodec() diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index 982a4e726..e202cd6d8 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -15,11 +15,12 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" tmcrypto "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" + + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) var _ Keybase = dbKeybase{} diff --git a/crypto/keys/keybase_test.go b/crypto/keys/keybase_test.go index 3c7f98060..bc7783b67 100644 --- a/crypto/keys/keybase_test.go +++ b/crypto/keys/keybase_test.go @@ -13,8 +13,9 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/cosmos/cosmos-sdk/types" dbm "github.com/tendermint/tendermint/libs/db" + + "github.com/cosmos/cosmos-sdk/types" ) func init() { diff --git a/crypto/keys/mintkey/mintkey.go b/crypto/keys/mintkey/mintkey.go index 35cb9ccab..3b06415e2 100644 --- a/crypto/keys/mintkey/mintkey.go +++ b/crypto/keys/mintkey/mintkey.go @@ -11,8 +11,9 @@ import ( "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" cmn "github.com/tendermint/tendermint/libs/common" + + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) const ( diff --git a/crypto/keys/types.go b/crypto/keys/types.go index b4b328516..14d050961 100644 --- a/crypto/keys/types.go +++ b/crypto/keys/types.go @@ -1,9 +1,10 @@ package keys import ( - ccrypto "github.com/cosmos/cosmos-sdk/crypto" "github.com/tendermint/tendermint/crypto" + ccrypto "github.com/cosmos/cosmos-sdk/crypto" + "github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/types" ) diff --git a/docs/RELEASE_TEST_SCRIPT.md b/docs/RELEASE_TEST_SCRIPT.md index 725507958..c1eb093d8 100644 --- a/docs/RELEASE_TEST_SCRIPT.md +++ b/docs/RELEASE_TEST_SCRIPT.md @@ -1,17 +1,17 @@ This document should contain plain english instructions for testing functionality on `gaiad`. This “Script” is supposed to be run by 2 people who will each spin up a `gaiad` node and run the series of prompts below. -- [Create a network of 2 nodes](getting-started/create-testnet.md) -- [Generate an account](sdk/clients.md) -- [Send funds from one account to the other](sdk/clients.md) -- [Create a validator](validators/validator-setup.md) -- [Edit a validator](validators/validator-setup.md) -- [Delegate to validator](sdk/clients.md) -- [Unbond from a validator](sdk/clients.md) -- [View validators and verify output](validators/validator-setup.md) -- [Query network status](getting-started/full-node.md) -- [Create a proposal](validators/validator-setup.md) -- [Query a proposal](validators/validator-setup.md) -- [Vote on a proposal](validators/validator-setup.md) -- [Query status of a proposal](validators/validator-setup.md) -- [Query the votes on a proposal](validators/validator-setup.md) -- [Export state and reload](getting-started/create-testnet.md) +- [Create a network of 2 nodes](./gaia/deploy-testnet.md) +- [Generate an account](./gaia/gaiacli.md) +- [Send funds from one account to the other](./gaia/gaiacli.md) +- [Create a validator](./gaia/validators/validator-setup.md) +- [Edit a validator](./gaia/alidators/validator-setup.md) +- [Delegate to validator](./gaia/gaiacli.md) +- [Unbond from a validator](./gaia/gaiacli.md) +- [View validators and verify output](./gaia/validators/validator-setup.md) +- [Query network status](./gaia/join-testnet.md#run-a-full-node) +- [Create a proposal](./gaia/validators/validator-setup.md) +- [Query a proposal](./gaia/validators/validator-setup.md) +- [Vote on a proposal](./gaia/validators/validator-setup.md) +- [Query status of a proposal](./gaia/validators/validator-setup.md) +- [Query the votes on a proposal](./gaia/validators/validator-setup.md) +- [Export state and reload](./gaia/join-testnet.md) diff --git a/docs/_attic/sdk/core/examples/app2_test.go b/docs/_attic/sdk/core/examples/app2_test.go index b7c94bbcf..0712e7add 100644 --- a/docs/_attic/sdk/core/examples/app2_test.go +++ b/docs/_attic/sdk/core/examples/app2_test.go @@ -3,9 +3,10 @@ package app import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" ) diff --git a/docs/clients/lite/getting_started.md b/docs/clients/lite/getting_started.md index 15bc8a279..faa3ea91b 100644 --- a/docs/clients/lite/getting_started.md +++ b/docs/clients/lite/getting_started.md @@ -13,7 +13,7 @@ To start a REST server, we need to specify the following parameters: For example:: ```bash -gaiacli advanced rest-server --chain-id=test \ +gaiacli rest-server --chain-id=test \ --laddr=tcp://localhost:1317 \ --node tcp://localhost:26657 \ --trust-node=false @@ -22,11 +22,11 @@ gaiacli advanced rest-server --chain-id=test \ The server listens on HTTPS by default. You can set the SSL certificate to be used by the server with these additional flags: ```bash -gaiacli advanced rest-server --chain-id=test \ +gaiacli rest-server --chain-id=test \ --laddr=tcp://localhost:1317 \ --node tcp://localhost:26657 \ --trust-node=false \ - --certfile=mycert.pem --keyfile=mykey.key + --ssl-certfile=mycert.pem --ssl-keyfile=mykey.key ``` If no certificate/keyfile pair is supplied, a self-signed certificate will be generated and its fingerprint printed out. diff --git a/docs/examples/basecoin/app/app.go b/docs/examples/basecoin/app/app.go index f534c9128..a469e0b2a 100644 --- a/docs/examples/basecoin/app/app.go +++ b/docs/examples/basecoin/app/app.go @@ -4,6 +4,12 @@ import ( "encoding/json" "os" + abci "github.com/tendermint/tendermint/abci/types" + cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" + bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types" @@ -11,11 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" - abci "github.com/tendermint/tendermint/abci/types" - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" ) const ( diff --git a/docs/examples/basecoin/app/app_test.go b/docs/examples/basecoin/app/app_test.go index 64bc6a86e..4dae71194 100644 --- a/docs/examples/basecoin/app/app_test.go +++ b/docs/examples/basecoin/app/app_test.go @@ -4,15 +4,16 @@ import ( "os" "testing" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) func setGenesis(baseApp *BasecoinApp, accounts ...*types.AppAccount) (types.GenesisState, error) { diff --git a/docs/examples/basecoin/cli_test/cli_test.go b/docs/examples/basecoin/cli_test/cli_test.go index 635b54c3c..7e6a648df 100644 --- a/docs/examples/basecoin/cli_test/cli_test.go +++ b/docs/examples/basecoin/cli_test/cli_test.go @@ -6,10 +6,11 @@ import ( "os" "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" - "github.com/stretchr/testify/require" ) var ( diff --git a/docs/examples/basecoin/cmd/basecli/main.go b/docs/examples/basecoin/cmd/basecli/main.go index 6e274123e..fe681a3ad 100644 --- a/docs/examples/basecoin/cmd/basecli/main.go +++ b/docs/examples/basecoin/cmd/basecli/main.go @@ -9,6 +9,9 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app" + "github.com/spf13/cobra" + "github.com/tendermint/tendermint/libs/cli" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" @@ -20,8 +23,6 @@ import ( slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" - "github.com/spf13/cobra" - "github.com/tendermint/tendermint/libs/cli" ) const ( diff --git a/docs/examples/basecoin/cmd/basecoind/main.go b/docs/examples/basecoin/cmd/basecoind/main.go index 383a843b2..9cb246671 100644 --- a/docs/examples/basecoin/cmd/basecoind/main.go +++ b/docs/examples/basecoin/cmd/basecoind/main.go @@ -11,10 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" gaiaInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app" - "github.com/cosmos/cosmos-sdk/server" "github.com/spf13/cobra" "github.com/spf13/viper" abci "github.com/tendermint/tendermint/abci/types" @@ -23,6 +19,11 @@ import ( dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app" + "github.com/cosmos/cosmos-sdk/server" ) const ( diff --git a/docs/examples/democoin/app/app_test.go b/docs/examples/democoin/app/app_test.go index 93cef936c..200103466 100644 --- a/docs/examples/democoin/app/app_test.go +++ b/docs/examples/democoin/app/app_test.go @@ -4,16 +4,17 @@ import ( "os" "testing" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/docs/examples/democoin/types" - "github.com/cosmos/cosmos-sdk/docs/examples/democoin/x/cool" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/docs/examples/democoin/types" + "github.com/cosmos/cosmos-sdk/docs/examples/democoin/x/cool" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) func setGenesis(bapp *DemocoinApp, trend string, accs ...auth.BaseAccount) error { diff --git a/docs/examples/democoin/cli_test/cli_test.go b/docs/examples/democoin/cli_test/cli_test.go index 9a3cba0df..1aa9d94ac 100644 --- a/docs/examples/democoin/cli_test/cli_test.go +++ b/docs/examples/democoin/cli_test/cli_test.go @@ -8,9 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" - "github.com/stretchr/testify/require" ) var ( diff --git a/docs/examples/democoin/cmd/democoind/main.go b/docs/examples/democoin/cmd/democoind/main.go index 8f52340f4..f0553ee5d 100644 --- a/docs/examples/democoin/cmd/democoind/main.go +++ b/docs/examples/democoin/cmd/democoind/main.go @@ -6,11 +6,12 @@ import ( "io" "os" - "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/p2p" + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" diff --git a/docs/examples/democoin/mock/validator.go b/docs/examples/democoin/mock/validator.go index 1d10c48b2..ee8e497cb 100644 --- a/docs/examples/democoin/mock/validator.go +++ b/docs/examples/democoin/mock/validator.go @@ -3,8 +3,9 @@ package mock import ( "bytes" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // Validator implements sdk.Validator diff --git a/docs/examples/democoin/x/cool/app_test.go b/docs/examples/democoin/x/cool/app_test.go index 3725f7b9b..7e9e29f24 100644 --- a/docs/examples/democoin/x/cool/app_test.go +++ b/docs/examples/democoin/x/cool/app_test.go @@ -3,13 +3,14 @@ package cool import ( "testing" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" bank "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" ) var ( diff --git a/docs/examples/democoin/x/pow/mine.go b/docs/examples/democoin/x/pow/mine.go index bf1c64cd4..3c24c1264 100644 --- a/docs/examples/democoin/x/pow/mine.go +++ b/docs/examples/democoin/x/pow/mine.go @@ -5,8 +5,9 @@ import ( "math" "strconv" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // generate the mine message diff --git a/docs/gaia/join-testnet.md b/docs/gaia/join-testnet.md index e5cfcf4d2..b09b8fc1c 100644 --- a/docs/gaia/join-testnet.md +++ b/docs/gaia/join-testnet.md @@ -1,4 +1,4 @@ -# Join the latest public testnet +# Join Public Testnet ::: tip Current Testnet See the [testnet repo](https://github.com/cosmos/testnets) for diff --git a/docs/gaia/ledger.md b/docs/gaia/ledger.md index e4bf9ac15..ce03c88b2 100644 --- a/docs/gaia/ledger.md +++ b/docs/gaia/ledger.md @@ -1,4 +1,4 @@ -# Ledger // Cosmos +# Ledger Nano Support ### Ledger Support for account keys diff --git a/docs/gaia/validators/security.md b/docs/gaia/validators/security.md index 5ccf98814..a5072d719 100644 --- a/docs/gaia/validators/security.md +++ b/docs/gaia/validators/security.md @@ -1,4 +1,4 @@ -## Overview +## Validator Security Each validator candidate is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Validator candidates should commence their setup phase now in order to be on time for launch. @@ -49,4 +49,4 @@ By default, uppercase environment variables with the following prefixes will rep - `BC` (for democli or basecli flags) For example, the environment variable `GA_CHAIN_ID` will map to the command line flag `--chain-id`. Note that while explicit command-line flags will take precedence over environment variables, environment variables will take precedence over any of your configuration files. For this reason, it's imperative that you lock down your environment such that any critical parameters are defined as flags on the CLI or prevent modification of any environment variables. - \ No newline at end of file + diff --git a/docs/gaia/validators/validator-setup.md b/docs/gaia/validators/validator-setup.md index 12a63dd84..99858f429 100644 --- a/docs/gaia/validators/validator-setup.md +++ b/docs/gaia/validators/validator-setup.md @@ -1,4 +1,4 @@ -# Run a validator on the gaia public testnet +# Run a Validator on Public Testnet ::: tip Information on how to join the current testnet (`genesis.json` file and seeds) is held [in our `testnet` repo](https://github.com/cosmos/testnets/tree/master/latest). Please check there if you are looking to join our latest testnet. diff --git a/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.pdf b/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.pdf index 12e7d5906..0f7443104 100644 Binary files a/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.pdf and b/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.pdf differ diff --git a/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.tex b/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.tex index 969e77ec9..2a4c2ba39 100644 --- a/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.tex +++ b/docs/spec/spec-proposals/f1-fee-distribution/f1_fee_distr.tex @@ -2,7 +2,7 @@ \usepackage{hyperref} %opening -\title{F1 Fee Distribution Draft-00} +\title{F1 Fee Distribution Draft-01} \author{Dev Ojha} \begin{document} @@ -17,49 +17,71 @@ \section{F1 Fee Distribution} -In a proof of stake model, each validator has an associated stake, with delegators each contributing some amount to a validator's stake. -The validator is rewarded transaction fees every block for the service they are providing the network. -In the F1 distribution, each validator is permitted to take a commission from the fees they receive, and the remaining fees should be evenly distributed across the validator's delegators, such that every delegator the percentage of the validator's stake that came from the delegator is the proportion of that validator's remaining tx fees which they are getting. -Iterating over all delegators for every validator each block is too expensive for a blockchain environment. -Instead there is an explicit withdraw fees action which a delegator can take, which will give the delegator the same total amount of fees as though they were receiving it every block. +\subsection{Context} +In a proof of stake blockchain, each validator has an associated stake. +Transaction fees get rewarded to validators based on the incentive scheme of the underlying proof of stake model. +The fee distribution problem occurs in proof of stake blockchains supporting delegation, as there is a need to distribute a validator's fee rewards to its delegators. +The trivial solution of just giving the rewards to each delegator every block is too expensive to perform on-chain. +So instead fee distribution algorithms have delegators perform an explicit withdraw transaction, which when performed yields the same total amount of fees as if they had received them at every block. -Suppose a delegator delegates $x$ stake to a validator at block $h$. +This details F1, an approximation-free, slash-tolerant fee distribution algorithm which allows validator commission-rates, inflation rates, and fee proportions, which can all efficiently change per validator, every block. +The algorithm requires iterating over the validators every block, and withdraws require iterating over all of the corresponding validator's slashes whilst the delegator was bonded. +The former iteration is cheap, due to staking logic already requiring iteration over all validators, which causes the expensive state-reads to be cached. +The number of slashes is expected to be 0 or 1 for most validators, +so the latter term also meets the blockchain's efficiency needs. + +The key point of how F1 works is that it tracks how much rewards a delegator with 1 stake for a given validator would be entitled to if it had bonded at block 0 until the latest block. +When a delegator bonds at block $b$, the amount of rewards a delegator with 1 stake would have if bonded at block 0 until block $b$ is also persisted to state. +When the delegator withdraws, they receive the difference of these two values. +Since rewards are distributed according to stake-weighting, this amount of rewards can be scaled by the amount of stake a delegator had. +Section 1.2 describes this in more detail, with an argument for it being approximation free. +Section 2 details how to adapt this algorithm to handle commission rates, slashing, and inflation. + +\subsection{Base algorithm} +In this section, we show that the F1 base algorithm gives each delegator rewards identical to that which they'd receive in the naive and correct fee distribution algorithm that iterated over all delegators every block. + +Even distribution of a validators rewards amongst its validators weighted by stake means the following: +Suppose a delegator delegates $x$ stake to a validator $v$ at block $h$. Let the amount of stake the validator has at block $i$ be $s_i$ and the amount of fees they receive at this height be $f_i$. -Then if a delegator contributing $x$ stake decides to withdraw at block $n$, the rewards they receive is +Then if a delegator contributing $x$ stake decides to withdraw at block $n$, the rewards they receive are $$\sum_{i = h}^{n} \frac{x}{s_i}f_i = x \sum_{i = h}^{n} \frac{f_i}{s_i}$$ -However $s_i$ will not change every block. -It only changes if the validator gets slashed, or if someone new has bonded or unbonded. -Handling slashes is relegated to \autoref{ssec:slashing}. -Define a period as the set of blocks between two changes in a given validator's total stake. +Note that $s_i$ does not change every block, +it only changes if the validator gets slashed, +or if any delegator alters the amount they have delegated. +We'll relegate handling of slashes to \autoref{ssec:slashing}, +and only consider the case with no slashing here. +We can change the iteration from being over every block, to instead being over the set of blocks between two changes in validator $v$'s total stake. +Let each of these set of blocks be called a period. A new period begins every time that validator's total stake changes. -The above iteration will be converted to iteration over periods. Let the total amount of stake for the validator in period $p$ be $n_p$. -Let $T_p$ be the total fees this validator accrued within this period. +Let $T_p$ be the total fees that validator $v$ accrued in period $p$. Let $h$ be the start of period $p_{init}$, and height $n$ be the end of $p_{final}$. It follows that $$x \sum_{i = h}^{n} \frac{f_i}{s_i} = x \sum_{p = p_{init}}^{p_{final}} \frac{T_p}{n_p}$$ -Let $p_0$ represent the period from when the validator first bonded until the first change to the validators stake. -The central idea to the F1 model is that at the end of the $k$th period, the following is stored at a state location indexable by $k$: $\sum_{i=0}^{k}\frac{T_i}{n_i}$. -When a delegator wants to delegate or withdraw their reward, they first create a new entry in state to end the current period. Let the index of the current period be $f$. -Then this entry is created using the previous entry as follows: $$\sum_{i=0}^{f}\frac{T_i}{n_i} = \sum_{i=0}^{f-1}\frac{T_i}{n_i} + \frac{T_f}{n_f} = entry_{f-1} + \frac{T_f}{n_f}$$ +Let $p_0$ represent the period which begins when the validator first bonds. +The central idea to the F1 model is that at the end of the $k$th period, +the following is stored at a state location indexable by $k$: $\sum_{i=0}^{k}\frac{T_i}{n_i}$. +Let the index of the current period be $f$. +When a delegator wants to delegate or withdraw their reward, they first create a new entry in state to end the current period. +Then this entry is created using the previous entry as follows: +$$Entry_f = \sum_{i=0}^{f}\frac{T_i}{n_i} = \sum_{i=0}^{f-1}\frac{T_i}{n_i} + \frac{T_f}{n_f} = Entry_{f-1} + \frac{T_f}{n_f}$$ Where $T_f$ is the fees the validator has accrued in period $f$, and $n_f$ is the validators total amount of stake in period $f$. -The withdrawer's delegation object has the index $k$ for the period which they started accruing fees for. -Thus the reward they should receive when withdrawing is: +The withdrawer's delegation object has the index $k$ for the period which they ended by bonding. (They start receiving rewards for period $k + 1$) +The reward they should receive when withdrawing is: -$$x\left(entry_f - entry_k\right) = x\left(\left(\sum_{i=0}^{f}\frac{T_i}{n_i}\right) - \left(\sum_{i=0}^{k}\frac{T_i}{n_i}\right)\right) = x \sum_{i = k}^{f} \frac{T_i}{n_i}$$ +$$x \sum_{i = k + 1}^{f} \frac{T_i}{n_i} = x\left(\left(\sum_{i=0}^{f}\frac{T_i}{n_i}\right) - \left(\sum_{i=0}^{k}\frac{T_i}{n_i}\right)\right) = x\left(Entry_f - Entry_k\right)$$ -The first summation is the state entry for $f$, and the second sum is the state entry at $k$. -It is clear from the equations that this payout mechanism maintains correctness, and required no iterations. +It is clear from the equations that this payout mechanism maintains correctness, and requires no iterations. It just needed the two state reads for these entries. $T_f$ is a separate variable in state for the amount of fees this validator has accrued since the last update to its power. This variable is incremented at every block by however much fees this validator received that block. -On the update to the validators power, this variable is used to create the entry in state at $f$. +On the update to the validators power, this variable is used to create the entry in state at $f$, and is then reset to 0. This fee distribution proposal is agnostic to how all of the blocks fees are divied up between validators. -This creates many nice properties, for example only rewarding validators who signed that block. +This creates many nice properties, for example it is possible to only rewarding validators who signed that block. \section{Additional add-ons} \subsection{Commission Rates} @@ -68,13 +90,14 @@ This can easily be done as follows: In block $h$ a validator receives $f_h$ fees. Instead of incrementing that validators ``total accrued fees this period variable" by $f_h$, it is instead incremented by $(1 - commission\_rate) * f_p$. -Then $commission\_rate * f_p$ is deposited directly to the validator. -This scheme allow for updates to a validator's commission rate every block if desired. +Then $commission\_rate * f_p$ is deposited directly to the validator's account. +This allows for efficient updates to a validator's commission rate every block if desired. +More generally, each validator could have a function which takes their fees as input, and outputs a set of outputs to pay these fees too. (i.e. x\% going to themselves, y\% to delegators, z\% burnt) \subsection{Slashing} \label{ssec:slashing} -Slashing is distinct from withdrawals, since not only does it lower the validators total amount of stake, but it also lowers each of its delegator's stake by a fixed percentage. -Since noone is charged gas for slashes, a slash cannot iterate over all delegators. +Slashing is distinct from withdrawals, since it lowers the stake of all of the delegator's by a fixed percentage. +Since no one is charged gas for slashes, a slash cannot iterate over all delegators. Thus we can no longer just multiply by $x$ over the difference in stake. The solution here is to instead store each period created by a slash in the validators state. Then when withdrawing, you must iterate over all slashes between when you started and ended. @@ -85,24 +108,94 @@ When there are multiple slashes, you just account for the accumulated slash fact In practice this will not really be an efficiency hit, as we can expect most validators to have no slashes. Validators that get slashed a lot will naturally lose their delegators. -A malicious validator that gets itself slashed many times would increase the gas to withdraw linearly, but the economic loss of funds due to the slashes should far out-weigh the extra overhead the withdrawer must pay for due to the gas. +A malicious validator that gets itself slashed many times would increase the gas to withdraw linearly, but the economic loss of funds due to the slashes should far out-weigh the extra overhead the honest withdrawer must pay for due to the gas. \subsection{Inflation} -Inflation is the idea that we want every staked coin to grow in value as time progresses. Each block, every staked token should each be rewarded $x$ staking tokens as inflation, where $x$ is calculated from function which takes state and the block information as input. This also allows for many seemless upgrade's to $x$'s algorithm. This can be added efficiently into the fee distribution model as follows: +Inflation is the idea that we want every staked coin to create more staking tokens as time progresses. +The purpose being to drive down the relative worth of unstaked tokens. +Each block, every staked token should produce $x$ staking tokens as inflation, where $x$ is calculated from a function $inflation$ which takes state and the block information as input. +Let $x_i$ represent the evaluation of $inflation$ in the $i$th block. +The goal of this section is to auto-bond inflation in the fee distribution model without iteration. +This is done by preserving the invariant that every state entry contains the rewards one would have if they had bonded one stake at genesis until that corresponding block. -Make each block have an inflation number, by which every staked token should produce $x$ additional staking tokens. In state there is a variable for the sum of all such inflation numbers. Then each period will store this total inflation sum in addition to $\sum_{i=0}^{end}\frac{T_i}{n_i}$. When withdrawing perform a subtraction on the inflation sums at the end and at the start to see how many new staking tokens to produce per staked token. +In state a variable should be kept for the number of tokens one would have now due to inflation, +given that they bonded one token at genesis. +This is $\prod_{0}^{now} (1 + x_i)$. +Each period now stores this total inflation product along with what it already stores per-period. -This works great in the model where the inflation rate should be dynamic each block, but apply the same to each validator. Inflation creation can trivially be epoched as long as inflation isn't required within the epoch, through changes to the $x$ function. +Let $R_i$ be the fee rewards in block $i$, and $n_i$ be the total amount bonded to that validator in that block. +The correct amount of rewards which 1 token at genesis should have now is: +$$Reward(now) = \sum_{i = 0}^{now}\left(\prod_{j = 0}^{i} 1 + x_j \right) * \frac{R_i}{n_i}$$ +The term in the sum is the amount of stake one stake becomes due to inflation, multiplied by the amount of fees per stake. -Note that this process is extremely efficient. +Now we cast this into the period frame of view. +Recall that we build the rewards by creating a state entry for the rewards of the previous period, and keeping track of the rewards within this period. +Thus we first define the correct amount of rewards for each successive period, proving correctness of this via induction. +We then show that the state entry that gets efficiently built up block by block is equal to this value for the latest period. -The above can be trivially amended if we want inflation to proceed differently for different validators each block. (e.g. depending on who was offline) It can also be made to be easily adapted in a live chain. It is unclear if either of these two are more desirable settings. +Let $start, end$ denote the start/end of a period. + +Suppose that $\forall f > 0$, $Reward(end(f))$ is correctly constructed as +$$Reward(end(f)) = Reward(end(f-1)) + \sum_{i = start(f)}^{end(f)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i}$$ +and that for $f = 0$, $Reward(end(0)) = 0$. +(With period 1 being defined as the period that has the first bond into it) +It must be shown that assuming the supposition $\forall f \leq f_0$, $$Reward(end(f_0 + 1)) = Reward(end(f_0)) + \sum_{i = start(f_0 + 1)}^{end(f_0 + 1)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i}$$ +Using the definition of $Reward$, it follows that: +$$\sum_{i = 0}^{end(f_0 + 1)}\left(\prod_{j = 0}^{i} 1 + x_j \right) * \frac{R_i}{n_i} = \sum_{i = 0}^{end(f_0)}\left(\prod_{j = 0}^{i} 1 + x_j \right) * \frac{R_i}{n_i} + \sum_{i = start(f_0 + 1)}^{end(f_0 + 1)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i}$$ + +Since the first summation on the right hand side is $Reward(end(f_0))$, the supposition is proven true. +Consequently, the reward for just period $f$ adjusted for the amount of inflation 1 token at genesis would produce, is: +$$\sum_{i = start(f)}^{end(f)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i}$$ + +TODO: make this proof + pre-amble less verbose, and just wrap up into a lemma. +Maybe just leave this proof or the last part to the reader, since it easily follows from summation bounds. + +Now note that +$$\sum_{i = start(f)}^{end(f)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i} = \left(\prod_{j = 0}^{end(f - 1)} 1 + x_j \right)\sum_{i = start(f)}^{end(f)}\left(\prod_{j = start(f)}^{i} 1 + x_j \right) \frac{R_i}{n_i}$$ +By definition of period, and inflation being applied every block, \\ +$n_i = n_{start(f)}\left(\prod_{j = start(f)}^{i} 1 + x_j \right)$. This cancels out the product in the summation, therefore +$$\sum_{i = start(f)}^{end(f)}\left(\prod_{j = 0}^{i} 1 + x_j \right) \frac{R_i}{n_i} = \left(\prod_{j = 0}^{end(f - 1)} 1 + x_j \right)\frac{\sum_{i = start(f)}^{end(f)}R_i}{n_{start(f)}}$$ + +Thus every block, each validator just has to add the total amount of fees (The $R_i$ term) that goes to delegates to some per-period term. +When creating a new period, $n_{start(f)}$ can be cached in state, and the product is already stored in the previous periods state entry. +You then get the next period's $n_{start(f)}$ from the current tm-power entry. +This is thus extremely efficient per block. + +When withdrawing, you take the difference as before, +which yields the amount of rewards you would have obtained with $(\prod_0^{begin\ bonding\ period}1 + x)$ stake from the block you began bonding at until now. +$(\prod_0^{begin\ bonding\ period}1 + x)$ is known, since its included in the state entry for when you bonded. +You then divide the entitled fees by $(\prod_0^{begin\ bonding\ period}1 + x)$ to normalize it to being the amount of rewards you're entitled to from 1 stake at that block to now. +Then as before, you multiply by the amount of stake you had initially bonded. +TODO: (Does the difference equating to that make sense, or should it be shown explicitly) + +Note that the inflation function could vary per block, +and per validator if ever a need rose. +If the inflation rate is the same for everyone then there can be a single global store for the entries corresponding to the product of inflations. +Inflation creation can trivially be epoched as long as inflation isn't required within the epoch, through changes to the $inflation$ function. + +Again note that this process is extremely efficient. + +\subsection{Withdrawing with no iteration over slashes} +TODO: Fill this out. +Core idea: you use the same mechanism as previously, but you just make that blocks $x_j$ term negative. +(So a $20\%$ slash would be equivalent to an inflation on that validator of $-20\%$) +This foregoes the constant inflation per validator, may or may not be worth it depending on expected number of slashes + +\subsection{Auto bonding fees} +TODO: Fill this out. +Core idea: you use the same mechanism as previously, but you just don't take that optimization with $n_{i}$ and the $n_{start}$ relation. +Fairly simple to do. \subsection{Delegation updates} -Updating your delegation amount is equivalent to withdrawing earned rewards and a fully independent new delegation occuring in the same block. +Updating your delegation amount is equivalent to withdrawing earned rewards and a fully independent new delegation occurring in the same block. +The same applies for redelegation. +From the view of fee distribution, partial redelegation is the same as a delegation update + a new delegation. \subsection{Jailing / being kicked out of the validator set} -This basically requires no change. In each block you only iterate over the currently bonded validators. So you simply don't update the "total accrued fees this period" variable for jailed / non-bonded validators. Withdrawing requires \textit{no} special casing here! +This basically requires no change. +In each block you only iterate over the currently bonded validators. +So you simply don't update the "total accrued fees this period" variable for jailed / non-bonded validators. +Withdrawing requires \textit{no} special casing here! \section{State pruning} You will notice that in the main scheme there was no note for pruning entries from state. @@ -110,11 +203,20 @@ We can in fact prune quite effectively. Suppose for the sake of exposition that there is at most one delegation / withdrawal to a particular validator in any given block. Then each delegation is responsible for one addition to state. Only the next period, and this delegator's withdrawal could depend on this entry. Thus once this delegator withdraws, this state entry can be pruned. -For the entry created by the delegator's withdrawal, that is only required by the creation of the next period. Thus once the next period is created, that withdrawal's period can be deleted. +For the entry created by the delegator's withdrawal, that is only required by the creation of the next period. +Thus once the next period is created, that withdrawal's period can be deleted. -This can be easily adapted to the case where there are multiple delegations / withdrawals per block. Keep a counter per state entry for how many delegations need to be cleared. (So 1 for each delegation in that block which created that period, 0 for each withdrawal) When creating a new period, check that the previous period (which had to be read anyway) doesn't have a count of 0. If it does have a count of 0, delete it. When withdrawing, decrement the period which created this delegation's counter by 1. If that counter is now 0, delete that period. +This can be easily adapted to the case where there are multiple delegations / withdrawals per block. +Keep a counter per state entry for how many delegations need to be cleared. +(So 1 for each delegation in that block which created that period, 0 for each withdrawal) +When creating a new period, check that the previous period (which had to be read anyway) doesn't have a count of 0. +If it does have a count of 0, delete it. +When withdrawing, decrement the period which created this delegation's counter by 1. +If that counter is now 0, delete that period. -The slash entries for a validator can only be pruned when all of that validator's delegators have their bonding period starting after the slash. This seems ineffective to keep track of, thus it is not worth it. Each slash should instead remain in state until the validator unbonds and all delegators have their fees withdrawn. +The slash entries for a validator can only be pruned when all of that validator's delegators have their bonding period starting after the slash. +This seems ineffective to keep track of, thus it is not worth it. +Each slash should instead remain in state until the validator unbonds and all delegators have their fees withdrawn. \section{Implementers Considerations} @@ -132,4 +234,16 @@ This is an extremely simple scheme with many nice benefits. Thus this scheme has efficiency improvements, simplicity improvements, and expressiveness improvements over the currently proposed schemes. With a correct fee distribution amongst the validator set, this solves the existing problem where one could withhold their signature for risk-free gain. +\section{TO DOs} + +\begin{itemize} + \item A global fee pool can be described. + \item Determine if auto-bonding fees is compatible with inflation and comission rates in conjunction + \item mention storage optimization in the uniform inflation and iteration over slashing case: only have one storage location w/ refcount of the product of inflation results + \item Remove iteration over slashes by the same normalization trick used in inflation + \item Add equation numbers + \item perhaps re-organize so that the no iteration +\end{itemize} + + \end{document} diff --git a/server/config/config_test.go b/server/config/config_test.go index e4d552ad2..d68d84415 100644 --- a/server/config/config_test.go +++ b/server/config/config_test.go @@ -3,8 +3,9 @@ package config import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestDefaultConfig(t *testing.T) { diff --git a/server/export.go b/server/export.go index 7b5ba4a69..aa30597da 100644 --- a/server/export.go +++ b/server/export.go @@ -7,10 +7,12 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/codec" - tmtypes "github.com/tendermint/tendermint/types" "io/ioutil" "path" + + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" ) const ( diff --git a/server/init.go b/server/init.go index e1655c27e..dd9e7b890 100644 --- a/server/init.go +++ b/server/init.go @@ -4,15 +4,18 @@ import ( "encoding/json" "errors" "fmt" - "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/tendermint/tendermint/crypto" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/crypto/keys" + + tmtypes "github.com/tendermint/tendermint/types" + clkeys "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - tmtypes "github.com/tendermint/tendermint/types" ) // SimpleGenTx is a simple genesis tx diff --git a/server/mock/app.go b/server/mock/app.go index 9e5af4498..2b0b8ed5e 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -3,9 +3,10 @@ package mock import ( "encoding/json" "fmt" - "github.com/tendermint/tendermint/types" "path/filepath" + "github.com/tendermint/tendermint/types" + abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" diff --git a/server/mock/app_test.go b/server/mock/app_test.go index a5f2a078b..707c22c85 100644 --- a/server/mock/app_test.go +++ b/server/mock/app_test.go @@ -1,9 +1,10 @@ package mock import ( - "github.com/tendermint/tendermint/types" "testing" + "github.com/tendermint/tendermint/types" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" diff --git a/server/test_helpers.go b/server/test_helpers.go index 4347bad6c..148f63a48 100644 --- a/server/test_helpers.go +++ b/server/test_helpers.go @@ -2,12 +2,13 @@ package server import ( "fmt" - "github.com/cosmos/cosmos-sdk/client" "io/ioutil" "net" "os" "testing" + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/viper" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/cli" diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 5aeacf92f..33994b0cb 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -3,15 +3,17 @@ package server import ( "fmt" - "github.com/cosmos/cosmos-sdk/codec" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/codec" + tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" pvm "github.com/tendermint/tendermint/privval" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" ) // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout diff --git a/server/util.go b/server/util.go index 3d4a9d0b6..5c07d1b46 100644 --- a/server/util.go +++ b/server/util.go @@ -13,15 +13,16 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/server/config" - "github.com/cosmos/cosmos-sdk/version" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/cli" tmflags "github.com/tendermint/tendermint/libs/cli/flags" "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server/config" + "github.com/cosmos/cosmos-sdk/version" ) // server context diff --git a/server/util_test.go b/server/util_test.go index 2c16759c9..fb4e73259 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -4,8 +4,9 @@ import ( "encoding/json" "testing" - "github.com/cosmos/cosmos-sdk/codec" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/codec" ) func TestInsertKeyJSON(t *testing.T) { diff --git a/store/dbstoreadapter.go b/store/dbstoreadapter.go index 8f4a1583c..76e673de5 100644 --- a/store/dbstoreadapter.go +++ b/store/dbstoreadapter.go @@ -3,8 +3,9 @@ package store import ( "io" - sdk "github.com/cosmos/cosmos-sdk/types" dbm "github.com/tendermint/tendermint/libs/db" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // Wrapper type for dbm.Db with implementation of KVStore diff --git a/store/list_test.go b/store/list_test.go index 396e2d1a1..6767457cd 100644 --- a/store/list_test.go +++ b/store/list_test.go @@ -4,8 +4,9 @@ import ( "math/rand" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestList(t *testing.T) { diff --git a/store/multistoreproof_test.go b/store/multistoreproof_test.go index db3b65cad..0f80657b8 100644 --- a/store/multistoreproof_test.go +++ b/store/multistoreproof_test.go @@ -3,10 +3,11 @@ package store import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tendermint/libs/db" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestVerifyIAVLStoreQueryProof(t *testing.T) { diff --git a/store/transientstore.go b/store/transientstore.go index a3ce89631..63b154c01 100644 --- a/store/transientstore.go +++ b/store/transientstore.go @@ -1,8 +1,9 @@ package store import ( - sdk "github.com/cosmos/cosmos-sdk/types" dbm "github.com/tendermint/tendermint/libs/db" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var _ KVStore = (*transientStore)(nil) diff --git a/types/context_test.go b/types/context_test.go index 0ab6c8dfc..3ccea2a8a 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -8,9 +8,10 @@ import ( dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) type MockLogger struct { diff --git a/types/decimal_test.go b/types/decimal_test.go index b35894771..fa6442f3a 100644 --- a/types/decimal_test.go +++ b/types/decimal_test.go @@ -6,8 +6,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/codec" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/codec" ) // create a decimal from a decimal string (ex. "1234.5678") diff --git a/types/errors.go b/types/errors.go index 46436531e..a54c9d71c 100644 --- a/types/errors.go +++ b/types/errors.go @@ -4,9 +4,10 @@ import ( "fmt" "strings" - "github.com/cosmos/cosmos-sdk/codec" cmn "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/codec" + abci "github.com/tendermint/tendermint/abci/types" ) @@ -43,6 +44,7 @@ const ( CodeMemoTooLarge CodeType = 13 CodeInsufficientFee CodeType = 14 CodeTooManySignatures CodeType = 15 + CodeGasOverflow CodeType = 16 // CodespaceRoot is a codespace for error codes in this file only. // Notice that 0 is an "unset" codespace, which can be overridden with @@ -143,6 +145,9 @@ func ErrInsufficientFee(msg string) Error { func ErrTooManySignatures(msg string) Error { return newErrorWithRootCodespace(CodeTooManySignatures, msg) } +func ErrGasOverflow(msg string) Error { + return newErrorWithRootCodespace(CodeGasOverflow, msg) +} //---------------------------------------- // Error & sdkError diff --git a/x/auth/account.go b/x/auth/account.go index 0fa601acc..f647601ca 100644 --- a/x/auth/account.go +++ b/x/auth/account.go @@ -3,9 +3,10 @@ package auth import ( "errors" + "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto" ) // Account is an interface used to store coins at a given address within state. diff --git a/x/auth/ante.go b/x/auth/ante.go index 3c8a0f9aa..91789dd22 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -5,10 +5,11 @@ import ( "encoding/hex" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" + + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index 20fec8896..9d76107fe 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -5,8 +5,6 @@ import ( "strings" "testing" - codec "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" @@ -14,6 +12,9 @@ import ( "github.com/tendermint/tendermint/crypto/multisig" "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/tendermint/tendermint/libs/log" + + codec "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" ) func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 39d9b6694..842299df8 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -6,15 +6,16 @@ import ( "io/ioutil" "os" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/go-amino" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/tendermint/go-amino" ) const ( diff --git a/x/auth/client/txbuilder/txbuilder_test.go b/x/auth/client/txbuilder/txbuilder_test.go index 4ff472fef..7b0a281d6 100644 --- a/x/auth/client/txbuilder/txbuilder_test.go +++ b/x/auth/client/txbuilder/txbuilder_test.go @@ -6,11 +6,12 @@ import ( "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/tendermint/tendermint/crypto/ed25519" ) var ( diff --git a/x/auth/keeper.go b/x/auth/keeper.go index 18e82c206..bf8b92da6 100644 --- a/x/auth/keeper.go +++ b/x/auth/keeper.go @@ -1,9 +1,10 @@ package auth import ( + "github.com/tendermint/tendermint/crypto" + codec "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto" ) var ( diff --git a/x/auth/keeper_bench_test.go b/x/auth/keeper_bench_test.go index 5ca414048..413cd6afd 100644 --- a/x/auth/keeper_bench_test.go +++ b/x/auth/keeper_bench_test.go @@ -3,10 +3,11 @@ package auth import ( "testing" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" ) func BenchmarkAccountMapperGetAccountFound(b *testing.B) { diff --git a/x/auth/keeper_test.go b/x/auth/keeper_test.go index b0ba2e74b..ad05c0f8e 100644 --- a/x/auth/keeper_test.go +++ b/x/auth/keeper_test.go @@ -3,13 +3,14 @@ package auth import ( "testing" - codec "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + + codec "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" ) func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) { diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go index 59edf7c13..2a8efaab4 100644 --- a/x/auth/stdtx.go +++ b/x/auth/stdtx.go @@ -4,13 +4,18 @@ import ( "encoding/json" "fmt" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/multisig" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" ) -var _ sdk.Tx = (*StdTx)(nil) +var ( + _ sdk.Tx = (*StdTx)(nil) + + maxGasWanted = uint64((1 << 63) - 1) +) // StdTx is a standard way to wrap a Msg with Fee and Signatures. // NOTE: the first signature is the fee payer (Signatures must not be nil). @@ -38,6 +43,9 @@ func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs } func (tx StdTx) ValidateBasic() sdk.Error { stdSigs := tx.GetSignatures() + if tx.Fee.Gas > maxGasWanted { + return sdk.ErrGasOverflow(fmt.Sprintf("invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted)) + } if !tx.Fee.Amount.IsNotNegative() { return sdk.ErrInsufficientFee(fmt.Sprintf("invalid fee %s amount provided", tx.Fee.Amount)) } diff --git a/x/auth/stdtx_test.go b/x/auth/stdtx_test.go index 1f2fefaca..3ef4b69cc 100644 --- a/x/auth/stdtx_test.go +++ b/x/auth/stdtx_test.go @@ -5,12 +5,13 @@ import ( "strings" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var ( @@ -120,6 +121,15 @@ func TestTxValidateBasic(t *testing.T) { require.Error(t, err) require.Equal(t, sdk.CodeTooManySignatures, err.Result().Code) + // require to fail with invalid gas supplied + badFee = newStdFee() + badFee.Gas = 9223372036854775808 + tx = newTestTx(ctx, nil, nil, nil, nil, badFee) + + err = tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeGasOverflow, err.Result().Code) + // require to pass when above criteria are matched privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0} tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee) diff --git a/x/bank/client/cli/broadcast.go b/x/bank/client/cli/broadcast.go index 126668364..1bcd811cd 100644 --- a/x/bank/client/cli/broadcast.go +++ b/x/bank/client/cli/broadcast.go @@ -4,11 +4,12 @@ import ( "io/ioutil" "os" + "github.com/spf13/cobra" + amino "github.com/tendermint/go-amino" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/spf13/cobra" - amino "github.com/tendermint/go-amino" ) // GetSignCommand returns the sign command diff --git a/x/bank/client/cli/sendtx.go b/x/bank/client/cli/sendtx.go index 1a7c444af..e61d6eb56 100644 --- a/x/bank/client/cli/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -1,6 +1,8 @@ package cli import ( + "os" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" @@ -8,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" bankClient "github.com/cosmos/cosmos-sdk/x/bank/client" - "os" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 7bb2640fd..27cbc043c 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -49,8 +49,11 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } diff --git a/x/bank/simulation/msgs.go b/x/bank/simulation/msgs.go index 78b1f1945..96df52f56 100644 --- a/x/bank/simulation/msgs.go +++ b/x/bank/simulation/msgs.go @@ -6,13 +6,14 @@ import ( "math/big" "math/rand" + "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/cosmos/cosmos-sdk/x/mock/simulation" - "github.com/tendermint/tendermint/crypto" ) // SingleInputSendTx tests and runs a single msg send w/ auth, with one input and one output, where both diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index ee82498e8..0a51b2e8e 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -3,6 +3,7 @@ package cli import ( "fmt" + "os" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -88,6 +89,10 @@ func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command { msg = types.NewMsgWithdrawDelegatorRewardsAll(delAddr) } + if cliCtx.GenerateOnly { + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) + } + // build and sign the transaction, then broadcast to Tendermint return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) }, diff --git a/x/distribution/client/module_client.go b/x/distribution/client/module_client.go index ba725e1f8..69734b08d 100644 --- a/x/distribution/client/module_client.go +++ b/x/distribution/client/module_client.go @@ -1,10 +1,11 @@ package client import ( - "github.com/cosmos/cosmos-sdk/client" - distCmds "github.com/cosmos/cosmos-sdk/x/distribution/client/cli" "github.com/spf13/cobra" amino "github.com/tendermint/go-amino" + + "github.com/cosmos/cosmos-sdk/client" + distCmds "github.com/cosmos/cosmos-sdk/x/distribution/client/cli" ) // ModuleClient exports all client functionality from this module diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index 7d05e82b1..35ad25e66 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -3,10 +3,11 @@ package keeper import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/stake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake" ) func TestAllocateTokensBasic(t *testing.T) { diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index 455ad14e8..67606cc84 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -3,9 +3,10 @@ package keeper import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake" - "github.com/stretchr/testify/require" ) func TestWithdrawDelegationRewardBasic(t *testing.T) { diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index f8eb0925d..a8c378424 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -3,9 +3,10 @@ package keeper import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/stretchr/testify/require" ) func TestSetGetPreviousProposerConsAddr(t *testing.T) { diff --git a/x/distribution/keeper/validator_test.go b/x/distribution/keeper/validator_test.go index fc9331959..58079241c 100644 --- a/x/distribution/keeper/validator_test.go +++ b/x/distribution/keeper/validator_test.go @@ -3,9 +3,10 @@ package keeper import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake" - "github.com/stretchr/testify/require" ) func TestWithdrawValidatorRewardsAllNoDelegator(t *testing.T) { diff --git a/x/distribution/types/dec_coin_test.go b/x/distribution/types/dec_coin_test.go index 5a326fa17..9b942f07c 100644 --- a/x/distribution/types/dec_coin_test.go +++ b/x/distribution/types/dec_coin_test.go @@ -3,9 +3,10 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestPlusDecCoin(t *testing.T) { diff --git a/x/distribution/types/delegator_info_test.go b/x/distribution/types/delegator_info_test.go index e15ad2930..5619fb4d1 100644 --- a/x/distribution/types/delegator_info_test.go +++ b/x/distribution/types/delegator_info_test.go @@ -3,8 +3,9 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestWithdrawRewards(t *testing.T) { diff --git a/x/distribution/types/fee_pool_test.go b/x/distribution/types/fee_pool_test.go index 73bda52fa..ceb908d7f 100644 --- a/x/distribution/types/fee_pool_test.go +++ b/x/distribution/types/fee_pool_test.go @@ -3,8 +3,9 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestUpdateTotalValAccum(t *testing.T) { diff --git a/x/distribution/types/test_common.go b/x/distribution/types/test_common.go index b77efd46c..480244ac3 100644 --- a/x/distribution/types/test_common.go +++ b/x/distribution/types/test_common.go @@ -1,9 +1,10 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var ( diff --git a/x/distribution/types/total_accum_test.go b/x/distribution/types/total_accum_test.go index 81f80a154..3984612ad 100644 --- a/x/distribution/types/total_accum_test.go +++ b/x/distribution/types/total_accum_test.go @@ -3,8 +3,9 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestTotalAccumUpdateForNewHeight(t *testing.T) { diff --git a/x/distribution/types/validator_info_test.go b/x/distribution/types/validator_info_test.go index 24c3eaee4..119eb6343 100644 --- a/x/distribution/types/validator_info_test.go +++ b/x/distribution/types/validator_info_test.go @@ -3,9 +3,10 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestTakeFeePoolRewards(t *testing.T) { diff --git a/x/gov/client/cli/query.go b/x/gov/client/cli/query.go index 4f0c86fea..06dabfcdd 100644 --- a/x/gov/client/cli/query.go +++ b/x/gov/client/cli/query.go @@ -5,13 +5,14 @@ import ( "strconv" "strings" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov" govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" - "github.com/spf13/cobra" - "github.com/spf13/viper" ) // GetCmdQueryProposal implements the query proposal command. diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 58ce91352..74c311ef4 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -5,21 +5,23 @@ import ( "os" "strconv" + "github.com/pkg/errors" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/gov" - "github.com/pkg/errors" "encoding/json" "io/ioutil" "strings" - govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/spf13/cobra" "github.com/spf13/viper" + + govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" ) const ( diff --git a/x/gov/client/cli/tx_test.go b/x/gov/client/cli/tx_test.go index e3aed05ff..73df8c290 100644 --- a/x/gov/client/cli/tx_test.go +++ b/x/gov/client/cli/tx_test.go @@ -1,10 +1,11 @@ package cli import ( - "github.com/spf13/viper" - "github.com/stretchr/testify/require" "io/ioutil" "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/require" ) func TestParseSubmitProposalFlags(t *testing.T) { diff --git a/x/gov/client/module_client.go b/x/gov/client/module_client.go index 456ddfbe7..1f67c9c07 100644 --- a/x/gov/client/module_client.go +++ b/x/gov/client/module_client.go @@ -1,10 +1,11 @@ package client import ( - "github.com/cosmos/cosmos-sdk/client" - govCli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" "github.com/spf13/cobra" amino "github.com/tendermint/go-amino" + + "github.com/cosmos/cosmos-sdk/client" + govCli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" ) // ModuleClient exports all client functionality from this module diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index 72abdb214..821da0cc7 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -10,9 +10,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov" - govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/gorilla/mux" "github.com/pkg/errors" + + govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" ) // REST Variable names @@ -77,8 +78,11 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } @@ -122,8 +126,11 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } @@ -161,8 +168,11 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } diff --git a/x/gov/depositsvotes.go b/x/gov/depositsvotes.go index 8e22f245d..3e2ac5673 100644 --- a/x/gov/depositsvotes.go +++ b/x/gov/depositsvotes.go @@ -4,8 +4,9 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/pkg/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // Vote diff --git a/x/gov/endblocker_test.go b/x/gov/endblocker_test.go index 47e903758..622d0968f 100644 --- a/x/gov/endblocker_test.go +++ b/x/gov/endblocker_test.go @@ -6,9 +6,10 @@ import ( "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - abci "github.com/tendermint/tendermint/abci/types" ) func TestTickExpiredDepositPeriod(t *testing.T) { diff --git a/x/gov/genesis.go b/x/gov/genesis.go index 8498e3b5a..7a8fab0b6 100644 --- a/x/gov/genesis.go +++ b/x/gov/genesis.go @@ -1,6 +1,7 @@ package gov import ( + "fmt" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -61,6 +62,34 @@ func DefaultGenesisState() GenesisState { // ValidateGenesis TODO https://github.com/cosmos/cosmos-sdk/issues/3007 func ValidateGenesis(data GenesisState) error { + threshold := data.TallyParams.Threshold + if threshold.IsNegative() || threshold.GT(sdk.OneDec()) { + return fmt.Errorf("Governance vote threshold should be positive and less or equal to one, is %s", + threshold.String()) + } + + veto := data.TallyParams.Veto + if veto.IsNegative() || veto.GT(sdk.OneDec()) { + return fmt.Errorf("Governance vote veto threshold should be positive and less or equal to one, is %s", + veto.String()) + } + + govPenalty := data.TallyParams.GovernancePenalty + if govPenalty.IsNegative() || govPenalty.GT(sdk.OneDec()) { + return fmt.Errorf("Governance vote veto threshold should be positive and less or equal to one, is %s", + govPenalty.String()) + } + + if data.DepositParams.MaxDepositPeriod > data.VotingParams.VotingPeriod { + return fmt.Errorf("Governance deposit period should be less than or equal to the voting period (%ds), is %ds", + data.VotingParams.VotingPeriod, data.DepositParams.MaxDepositPeriod) + } + + if !data.DepositParams.MinDeposit.IsValid() { + return fmt.Errorf("Governance deposit amount must be a valid sdk.Coins amount, is %s", + data.DepositParams.MinDeposit.String()) + } + return nil } diff --git a/x/gov/querier.go b/x/gov/querier.go index cde85bf94..8b985929e 100644 --- a/x/gov/querier.go +++ b/x/gov/querier.go @@ -3,9 +3,10 @@ package gov import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) // query endpoints supported by the governance Querier diff --git a/x/gov/querier_test.go b/x/gov/querier_test.go index 9ee71323e..01b611e19 100644 --- a/x/gov/querier_test.go +++ b/x/gov/querier_test.go @@ -4,10 +4,11 @@ import ( "strings" "testing" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" ) func getQueriedParams(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier) (DepositParams, VotingParams, TallyParams) { diff --git a/x/gov/tally_test.go b/x/gov/tally_test.go index 86564ed42..fc5cac910 100644 --- a/x/gov/tally_test.go +++ b/x/gov/tally_test.go @@ -5,11 +5,12 @@ import ( "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" ) diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 19c921971..704b663e6 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -43,8 +43,11 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } diff --git a/x/mock/app.go b/x/mock/app.go index 9251a95c0..066ac93dc 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -7,16 +7,17 @@ import ( "os" "sort" - bam "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + + bam "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) const chainID = "" diff --git a/x/mock/app_test.go b/x/mock/app_test.go index 1af0e4a03..098126d89 100644 --- a/x/mock/app_test.go +++ b/x/mock/app_test.go @@ -3,10 +3,11 @@ package mock import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) const msgRoute = "testMsg" diff --git a/x/mock/simulation/invariants.go b/x/mock/simulation/invariants.go index a3ae5f3c3..d30b67be9 100644 --- a/x/mock/simulation/invariants.go +++ b/x/mock/simulation/invariants.go @@ -4,9 +4,10 @@ import ( "fmt" "testing" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) // An Invariant is a function which tests a particular invariant. diff --git a/x/mock/test_utils.go b/x/mock/test_utils.go index 4d5fe05f3..9c24967ab 100644 --- a/x/mock/test_utils.go +++ b/x/mock/test_utils.go @@ -5,11 +5,12 @@ import ( "math/rand" "testing" - "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" ) // BigInterval is a representation of the interval [lo, hi), where diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 513710ce4..2e97414bd 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -1,13 +1,14 @@ package cli import ( + "os" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/slashing" - "os" "github.com/spf13/cobra" ) diff --git a/x/slashing/client/module_client.go b/x/slashing/client/module_client.go index 82efb5afe..2d7c6b6eb 100644 --- a/x/slashing/client/module_client.go +++ b/x/slashing/client/module_client.go @@ -1,10 +1,11 @@ package client import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" "github.com/spf13/cobra" amino "github.com/tendermint/go-amino" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" ) // ModuleClient exports all client functionality from this module diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index e55b6b9be..a95c01acf 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -3,12 +3,13 @@ package rest import ( "net/http" + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/slashing" - "github.com/gorilla/mux" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) { diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 5f33a1210..ec28f48ed 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -38,8 +38,11 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL return } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 61d366172..5137b1198 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -4,11 +4,12 @@ import ( "fmt" "time" + "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/params" stake "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/tendermint/tendermint/crypto" ) // Keeper of the slashing store diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index dd32ea3f8..fdf409c23 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -4,10 +4,11 @@ import ( "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/stake" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake" ) // Have to change these parameters for tests diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 03bd094af..41af4b9ae 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -4,9 +4,10 @@ import ( "encoding/binary" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // slashing begin block functionality diff --git a/x/stake/client/cli/flags.go b/x/stake/client/cli/flags.go index d571bef9e..97a62ebd9 100644 --- a/x/stake/client/cli/flags.go +++ b/x/stake/client/cli/flags.go @@ -29,8 +29,6 @@ const ( FlagGenesisFormat = "genesis-format" FlagNodeID = "node-id" FlagIP = "ip" - - FlagOutputDocument = "output-document" // inspired by wget -O ) // common flagsets to add to various functions diff --git a/x/stake/client/cli/utils.go b/x/stake/client/cli/utils.go index 502cb11ec..848e1725d 100644 --- a/x/stake/client/cli/utils.go +++ b/x/stake/client/cli/utils.go @@ -1,12 +1,13 @@ package cli import ( + "github.com/pkg/errors" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/pkg/errors" ) func getShares( diff --git a/x/stake/client/module_client.go b/x/stake/client/module_client.go index 5a08668dc..03a7c25e2 100644 --- a/x/stake/client/module_client.go +++ b/x/stake/client/module_client.go @@ -1,10 +1,11 @@ package client import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/spf13/cobra" amino "github.com/tendermint/go-amino" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/stake/client/cli" ) // ModuleClient exports all client functionality from this module diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 5788346f2..085d7e4e2 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -1,10 +1,11 @@ package rest import ( - "github.com/cosmos/cosmos-sdk/x/stake" "net/http" "strings" + "github.com/cosmos/cosmos-sdk/x/stake" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/client/utils" diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index 437d40e77..bb2bc0e7f 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -2,81 +2,72 @@ package rest import ( "bytes" - "io/ioutil" "net/http" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" - authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/gorilla/mux" - - ctypes "github.com/tendermint/tendermint/rpc/core/types" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, kb keys.Keybase) { r.HandleFunc( "/stake/delegators/{delegatorAddr}/delegations", - delegationsRequestHandlerFn(cdc, kb, cliCtx), + postDelegationsHandlerFn(cdc, kb, cliCtx), + ).Methods("POST") + r.HandleFunc( + "/stake/delegators/{delegatorAddr}/unbonding_delegations", + postUnbondingDelegationsHandlerFn(cdc, kb, cliCtx), + ).Methods("POST") + r.HandleFunc( + "/stake/delegators/{delegatorAddr}/redelegations", + postRedelegationsHandlerFn(cdc, kb, cliCtx), ).Methods("POST") } type ( msgDelegationsInput struct { - DelegatorAddr string `json:"delegator_addr"` // in bech32 - ValidatorAddr string `json:"validator_addr"` // in bech32 - Delegation sdk.Coin `json:"delegation"` + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 + Delegation sdk.Coin `json:"delegation"` } msgBeginRedelegateInput struct { - DelegatorAddr string `json:"delegator_addr"` // in bech32 - ValidatorSrcAddr string `json:"validator_src_addr"` // in bech32 - ValidatorDstAddr string `json:"validator_dst_addr"` // in bech32 - SharesAmount string `json:"shares"` + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // in bech32 + ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"` // in bech32 + SharesAmount sdk.Dec `json:"shares"` } msgBeginUnbondingInput struct { - DelegatorAddr string `json:"delegator_addr"` // in bech32 - ValidatorAddr string `json:"validator_addr"` // in bech32 - SharesAmount string `json:"shares"` - } - - // the request body for edit delegations - EditDelegationsReq struct { - BaseReq utils.BaseReq `json:"base_req"` - Delegations []msgDelegationsInput `json:"delegations"` - BeginUnbondings []msgBeginUnbondingInput `json:"begin_unbondings"` - BeginRedelegates []msgBeginRedelegateInput `json:"begin_redelegates"` + BaseReq utils.BaseReq `json:"base_req"` + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 + ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 + SharesAmount sdk.Dec `json:"shares"` } ) -// TODO: Split this up into several smaller functions, and remove the above nolint -// TODO: use sdk.ValAddress instead of sdk.AccAddress for validators in messages -// TODO: Seriously consider how to refactor...do we need to make it multiple txs? -// If not, we can just use CompleteAndBroadcastTxREST. -func delegationsRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { +func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req EditDelegationsReq + var req msgDelegationsInput - body, err := ioutil.ReadAll(r.Body) + err := utils.ReadRESTReq(w, r, cdc, &req) if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - err = cdc.UnmarshalJSON(body, &req) - if err != nil { - utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBasic(w) { + if !baseReq.ValidateBasic(w, cliCtx) { return } @@ -86,182 +77,98 @@ func delegationsRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx conte return } - // build messages - messages := make([]sdk.Msg, len(req.Delegations)+ - len(req.BeginRedelegates)+ - len(req.BeginUnbondings)) - - i := 0 - for _, msg := range req.Delegations { - delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if !bytes.Equal(info.GetPubKey().Address(), delAddr) { - utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") - return - } - - messages[i] = stake.MsgDelegate{ - DelegatorAddr: delAddr, - ValidatorAddr: valAddr, - Delegation: msg.Delegation, - } - - i++ + if !bytes.Equal(info.GetPubKey().Address(), req.DelegatorAddr) { + utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") + return } - for _, msg := range req.BeginRedelegates { - delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if !bytes.Equal(info.GetPubKey().Address(), delAddr) { - utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") - return - } - - valSrcAddr, err := sdk.ValAddressFromBech32(msg.ValidatorSrcAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - valDstAddr, err := sdk.ValAddressFromBech32(msg.ValidatorDstAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - shares, err := sdk.NewDecFromStr(msg.SharesAmount) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - messages[i] = stake.MsgBeginRedelegate{ - DelegatorAddr: delAddr, - ValidatorSrcAddr: valSrcAddr, - ValidatorDstAddr: valDstAddr, - SharesAmount: shares, - } - - i++ - } - - for _, msg := range req.BeginUnbondings { - delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if !bytes.Equal(info.GetPubKey().Address(), delAddr) { - utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") - return - } - - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - shares, err := sdk.NewDecFromStr(msg.SharesAmount) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - messages[i] = stake.MsgBeginUnbonding{ - DelegatorAddr: delAddr, - ValidatorAddr: valAddr, - SharesAmount: shares, - } - - i++ - } - - simulateGas, gas, err := client.ReadGasFlag(baseReq.Gas) + msg := stake.NewMsgDelegate(req.DelegatorAddr, req.ValidatorAddr, req.Delegation) + err = msg.ValidateBasic() if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - adjustment, ok := utils.ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment) - if !ok { + utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc) + } +} + +func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req msgBeginRedelegateInput + + err := utils.ReadRESTReq(w, r, cdc, &req) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - txBldr := authtxb.TxBuilder{ - Codec: cdc, - Gas: gas, - GasAdjustment: adjustment, - SimulateGas: simulateGas, - ChainID: baseReq.ChainID, + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBasic(w, cliCtx) { + return } - // sign messages - signedTxs := make([][]byte, len(messages[:])) - for i, msg := range messages { - // increment sequence for each message - txBldr = txBldr.WithAccountNumber(baseReq.AccountNumber) - txBldr = txBldr.WithSequence(baseReq.Sequence) - - baseReq.Sequence++ - - if utils.HasDryRunArg(r) || txBldr.SimulateGas { - newBldr, err := utils.EnrichCtxWithGas(txBldr, cliCtx, baseReq.Name, []sdk.Msg{msg}) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if utils.HasDryRunArg(r) { - utils.WriteSimulationResponse(w, newBldr.Gas) - return - } - - txBldr = newBldr - } - - if utils.HasGenerateOnlyArg(r) { - utils.WriteGenerateStdTxResponse(w, txBldr, []sdk.Msg{msg}) - return - } - - txBytes, err := txBldr.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg}) - if err != nil { - utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) - return - } - - signedTxs[i] = txBytes + info, err := kb.Get(baseReq.Name) + if err != nil { + utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + return } - // send - // XXX the operation might not be atomic if a tx fails - // should we have a sdk.MultiMsg type to make sending atomic? - results := make([]*ctypes.ResultBroadcastTxCommit, len(signedTxs[:])) - for i, txBytes := range signedTxs { - res, err := cliCtx.BroadcastTx(txBytes) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - results[i] = res + if !bytes.Equal(info.GetPubKey().Address(), req.DelegatorAddr) { + utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") + return } - utils.PostProcessResponse(w, cdc, results, cliCtx.Indent) + msg := stake.NewMsgBeginRedelegate(req.DelegatorAddr, req.ValidatorSrcAddr, req.ValidatorDstAddr, req.SharesAmount) + err = msg.ValidateBasic() + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc) + } +} + +func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req msgBeginUnbondingInput + + err := utils.ReadRESTReq(w, r, cdc, &req) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly) + cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate) + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBasic(w, cliCtx) { + return + } + + info, err := kb.Get(baseReq.Name) + if err != nil { + utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + return + } + + if !bytes.Equal(info.GetPubKey().Address(), req.DelegatorAddr) { + utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own delegator address") + return + } + + msg := stake.NewMsgBeginUnbonding(req.DelegatorAddr, req.ValidatorAddr, req.SharesAmount) + err = msg.ValidateBasic() + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/stake/client/rest/utils.go b/x/stake/client/rest/utils.go index 7f6edc193..d9ae457cf 100644 --- a/x/stake/client/rest/utils.go +++ b/x/stake/client/rest/utils.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/client/utils" @@ -11,7 +13,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/tags" - "github.com/gorilla/mux" rpcclient "github.com/tendermint/tendermint/rpc/client" ) diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index dfe5b7d1b..f747ca7a7 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -8,11 +8,12 @@ import ( "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" ) func TestInitGenesis(t *testing.T) { diff --git a/x/stake/keeper/key_test.go b/x/stake/keeper/key_test.go index 0658e4b24..f994c3920 100644 --- a/x/stake/keeper/key_test.go +++ b/x/stake/keeper/key_test.go @@ -5,10 +5,11 @@ import ( "math/big" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/stretchr/testify/assert" "github.com/tendermint/tendermint/crypto/ed25519" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake/types" ) var ( diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 9f89dd210..94418a962 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -6,9 +6,10 @@ import ( "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" - abci "github.com/tendermint/tendermint/abci/types" ) // TODO integrate with test_common.go helper (CreateTestInput) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index f52b41c44..c3ca811cd 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -227,15 +227,14 @@ func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Vali panic("validator expected but not found") } return validator - } else { - cachectx, _ := ctx.CacheContext() - keeper.ApplyAndReturnValidatorSetUpdates(cachectx) - validator, found := keeper.GetValidator(cachectx, validator.OperatorAddr) - if !found { - panic("validator expected but not found") - } - return validator } + cachectx, _ := ctx.CacheContext() + keeper.ApplyAndReturnValidatorSetUpdates(cachectx) + validator, found := keeper.GetValidator(cachectx, validator.OperatorAddr) + if !found { + panic("validator expected but not found") + } + return validator } func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 71b0edcd1..e328537a5 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -5,9 +5,10 @@ import ( "testing" "time" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" - abci "github.com/tendermint/tendermint/abci/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/x/stake/querier/querier.go b/x/stake/querier/querier.go index 13ff97ef3..70627f0b1 100644 --- a/x/stake/querier/querier.go +++ b/x/stake/querier/querier.go @@ -1,11 +1,12 @@ package querier import ( + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" - abci "github.com/tendermint/tendermint/abci/types" ) // query endpoints supported by the staking Querier diff --git a/x/stake/querier/querier_test.go b/x/stake/querier/querier_test.go index c13a37897..525f3691a 100644 --- a/x/stake/querier/querier_test.go +++ b/x/stake/querier/querier_test.go @@ -3,12 +3,13 @@ package querier import ( "testing" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" ) var ( diff --git a/x/stake/types/delegation_test.go b/x/stake/types/delegation_test.go index e75212257..ee7d81bf5 100644 --- a/x/stake/types/delegation_test.go +++ b/x/stake/types/delegation_test.go @@ -4,8 +4,9 @@ import ( "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestDelegationEqual(t *testing.T) { diff --git a/x/stake/types/msg.go b/x/stake/types/msg.go index 63d0afb5f..a6692a7f3 100644 --- a/x/stake/types/msg.go +++ b/x/stake/types/msg.go @@ -3,8 +3,9 @@ package types import ( "bytes" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // name to identify transaction routes diff --git a/x/stake/types/msg_test.go b/x/stake/types/msg_test.go index 4b4055fca..e5cb8a9f0 100644 --- a/x/stake/types/msg_test.go +++ b/x/stake/types/msg_test.go @@ -5,8 +5,9 @@ import ( "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var ( diff --git a/x/stake/types/pool_test.go b/x/stake/types/pool_test.go index 4541edd3d..f877df0b1 100644 --- a/x/stake/types/pool_test.go +++ b/x/stake/types/pool_test.go @@ -3,8 +3,9 @@ package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestPoolEqual(t *testing.T) { diff --git a/x/stake/types/test_utils.go b/x/stake/types/test_utils.go index b9d77ce9f..548cd316a 100644 --- a/x/stake/types/test_utils.go +++ b/x/stake/types/test_utils.go @@ -1,9 +1,10 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var (