diff --git a/CHANGELOG.md b/CHANGELOG.md index c741ba24a45b..4cf0eea5af1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ that parse log messages. older clients. * (x/auth) [\#5844](https://github.com/cosmos/cosmos-sdk/pull/5844) `tx sign` command now returns an error when signing is attempted with offline/multisig keys. * (client/keys) [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) Remove `keys update` command. +* (server) [\#5982](https://github.com/cosmos/cosmos-sdk/pull/5982) `--pruning` now must be set to `custom` if you want to customise the granular options. ### API Breaking Changes @@ -114,6 +115,7 @@ invalid or incomplete requests. * (x/genutil) [\#5938](https://github.com/cosmos/cosmos-sdk/pull/5938) Fix `InitializeNodeValidatorFiles` error handling. * (x/staking) [\#5949](https://github.com/cosmos/cosmos-sdk/pull/5949) Skip staking `HistoricalInfoKey` in simulations as headers are not exported. * (x/auth) [\#5950](https://github.com/cosmos/cosmos-sdk/pull/5950) Fix `IncrementSequenceDecorator` to use is `IsReCheckTx` instead of `IsCheckTx` to allow account sequence incrementing. +* (client) [\#5964](https://github.com/cosmos/cosmos-sdk/issues/5964) `--trust-node` is now false by default - for real. Users must ensure it is set to true if they don't want to enable the verifier. ### State Machine Breaking diff --git a/client/context/context.go b/client/context/context.go index c908a2044a82..7b0fa273155f 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -88,6 +88,7 @@ func NewCLIContextWithInputAndFrom(input io.Reader, from string) CLIContext { } } + trustNode := viper.GetBool(flags.FlagTrustNode) ctx := CLIContext{ Client: rpc, ChainID: viper.GetString(flags.FlagChainID), @@ -99,7 +100,7 @@ func NewCLIContextWithInputAndFrom(input io.Reader, from string) CLIContext { OutputFormat: viper.GetString(cli.OutputFlag), Height: viper.GetInt64(flags.FlagHeight), HomeDir: homedir, - TrustNode: viper.GetBool(flags.FlagTrustNode), + TrustNode: trustNode, UseLedger: viper.GetBool(flags.FlagUseLedger), BroadcastMode: viper.GetString(flags.FlagBroadcastMode), Simulate: viper.GetBool(flags.FlagDryRun), @@ -111,9 +112,13 @@ func NewCLIContextWithInputAndFrom(input io.Reader, from string) CLIContext { SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation), } + if offline { + return ctx + } + // create a verifier for the specific chain ID and RPC client verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) - if err != nil && viper.IsSet(flags.FlagTrustNode) { + if err != nil && !trustNode { fmt.Printf("failed to create verifier: %s\n", err) os.Exit(1) } diff --git a/client/context/context_test.go b/client/context/context_test.go index 7429fc18605d..626e430e0c63 100644 --- a/client/context/context_test.go +++ b/client/context/context_test.go @@ -21,15 +21,6 @@ func TestCLIContext_WithOffline(t *testing.T) { ctx := context.NewCLIContext() require.True(t, ctx.Offline) require.Nil(t, ctx.Client) - - viper.Reset() - - viper.Set(flags.FlagOffline, false) - viper.Set(flags.FlagNode, "tcp://localhost:26657") - - ctx = context.NewCLIContext() - require.False(t, ctx.Offline) - require.NotNil(t, ctx.Client) } func TestCLIContext_WithGenOnly(t *testing.T) { diff --git a/client/keys/add.go b/client/keys/add.go index c6a396e5d3a6..1e136ddf36f6 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -190,23 +190,16 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf coinType := uint32(viper.GetInt(flagCoinType)) account := uint32(viper.GetInt(flagAccount)) index := uint32(viper.GetInt(flagIndex)) + hdPath := viper.GetString(flagHDPath) - useBIP44 := !viper.IsSet(flagHDPath) - var hdPath string - - if useBIP44 { + if len(hdPath) == 0 { hdPath = hd.CreateHDPath(coinType, account, index).String() - } else { - hdPath = viper.GetString(flagHDPath) + } else if viper.GetBool(flags.FlagUseLedger) { + return errors.New("cannot set custom bip32 path with ledger") } // If we're using ledger, only thing we need is the path and the bech32 prefix. if viper.GetBool(flags.FlagUseLedger) { - - if !useBIP44 { - return errors.New("cannot set custom bip32 path with ledger") - } - bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() info, err := kb.SaveLedgerKey(name, hd.Secp256k1, bech32PrefixAccAddr, coinType, account, index) if err != nil { diff --git a/server/config/config.go b/server/config/config.go index 9752ae85273a..cba6917deab0 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -35,7 +35,9 @@ type BaseConfig struct { // InterBlockCache enables inter-block caching. InterBlockCache bool `mapstructure:"inter-block-cache"` - Pruning string `mapstructure:"pruning"` + Pruning string `mapstructure:"pruning"` + PruningKeepEvery string `mapstructure:"pruning-keep-every"` + PruningSnapshotEvery string `mapstructure:"pruning-snapshot-every"` } // Config defines the server's top level configuration @@ -74,9 +76,11 @@ func (c *Config) GetMinGasPrices() sdk.DecCoins { func DefaultConfig() *Config { return &Config{ BaseConfig{ - MinGasPrices: defaultMinGasPrices, - InterBlockCache: true, - Pruning: store.PruningStrategySyncable, + MinGasPrices: defaultMinGasPrices, + InterBlockCache: true, + Pruning: store.PruningStrategySyncable, + PruningKeepEvery: "0", + PruningSnapshotEvery: "0", }, } } diff --git a/server/config/toml.go b/server/config/toml.go index e556ed57656b..744595580c15 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -34,11 +34,16 @@ halt-time = {{ .BaseConfig.HaltTime }} # InterBlockCache enables inter-block caching. inter-block-cache = {{ .BaseConfig.InterBlockCache }} -# Pruning sets the pruning strategy: syncable, nothing, everything +# Pruning sets the pruning strategy: syncable, nothing, everything, custom # syncable: only those states not needed for state syncing will be deleted (keeps last 100 + every 10000th) # nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) # everything: all saved states will be deleted, storing only the current state +# custom: allows fine-grained control through the pruning-keep-every and pruning-snapshot-every options. pruning = "{{ .BaseConfig.Pruning }}" + +# These are applied if and only if the pruning strategy is custom. +pruning-keep-every = "{{ .BaseConfig.PruningKeepEvery }}" +pruning-snapshot-every = "{{ .BaseConfig.PruningSnapshotEvery }}" ` var configTemplate *template.Template diff --git a/server/pruning.go b/server/pruning.go index 712ed2a34c37..82820b666c60 100644 --- a/server/pruning.go +++ b/server/pruning.go @@ -1,6 +1,8 @@ package server import ( + "fmt" + "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/store" @@ -9,17 +11,23 @@ import ( // GetPruningOptionsFromFlags parses start command flags and returns the correct PruningOptions. // flagPruning prevails over flagPruningKeepEvery and flagPruningSnapshotEvery. // Default option is PruneSyncable. -func GetPruningOptionsFromFlags() store.PruningOptions { - if viper.IsSet(flagPruning) { - return store.NewPruningOptionsFromString(viper.GetString(flagPruning)) - } +func GetPruningOptionsFromFlags() (store.PruningOptions, error) { + strategy := viper.GetString(flagPruning) + switch strategy { + case "syncable", "nothing", "everything": + return store.NewPruningOptionsFromString(viper.GetString(flagPruning)), nil - if viper.IsSet(flagPruningKeepEvery) && viper.IsSet(flagPruningSnapshotEvery) { - return store.PruningOptions{ + case "custom": + opts := store.PruningOptions{ KeepEvery: viper.GetInt64(flagPruningKeepEvery), SnapshotEvery: viper.GetInt64(flagPruningSnapshotEvery), } - } + if !opts.IsValid() { + return opts, fmt.Errorf("invalid granular options") + } + return opts, nil - return store.PruneSyncable + default: + return store.PruningOptions{}, fmt.Errorf("unknown pruning strategy %s", strategy) + } } diff --git a/server/pruning_test.go b/server/pruning_test.go index 916f4e07dfba..cf4ba6bae1e3 100644 --- a/server/pruning_test.go +++ b/server/pruning_test.go @@ -14,6 +14,7 @@ func TestGetPruningOptionsFromFlags(t *testing.T) { name string initParams func() expectedOptions store.PruningOptions + wantErr bool }{ { name: "pruning", @@ -25,6 +26,7 @@ func TestGetPruningOptionsFromFlags(t *testing.T) { { name: "granular pruning", initParams: func() { + viper.Set(flagPruning, "custom") viper.Set(flagPruningSnapshotEvery, 1234) viper.Set(flagPruningKeepEvery, 4321) }, @@ -44,8 +46,14 @@ func TestGetPruningOptionsFromFlags(t *testing.T) { tt := tt t.Run(tt.name, func(j *testing.T) { viper.Reset() + viper.SetDefault(flagPruning, "syncable") tt.initParams() - require.Equal(t, tt.expectedOptions, GetPruningOptionsFromFlags()) + opts, err := GetPruningOptionsFromFlags() + if tt.wantErr { + require.Error(t, err) + return + } + require.Equal(t, tt.expectedOptions, opts) }) } } diff --git a/server/start.go b/server/start.go index c5bee58e8f1a..2f95724f3691 100644 --- a/server/start.go +++ b/server/start.go @@ -72,7 +72,8 @@ For profiling and benchmarking purposes, CPU profiling can be enabled via the '- which accepts a path for the resulting pprof file. `, PreRunE: func(cmd *cobra.Command, args []string) error { - return checkPruningParams() + _, err := GetPruningOptionsFromFlags() + return err }, RunE: func(cmd *cobra.Command, args []string) error { if !viper.GetBool(flagWithTendermint) { @@ -91,9 +92,9 @@ which accepts a path for the resulting pprof file. cmd.Flags().Bool(flagWithTendermint, true, "Run abci app embedded in-process with tendermint") cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address") cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file") - cmd.Flags().String(flagPruning, "syncable", "Pruning strategy: syncable, nothing, everything") - cmd.Flags().Int64(flagPruningKeepEvery, 0, "Define the state number that will be kept") - cmd.Flags().Int64(flagPruningSnapshotEvery, 0, "Defines the state that will be snapshot for pruning") + cmd.Flags().String(flagPruning, "syncable", "Pruning strategy: syncable, nothing, everything, custom") + cmd.Flags().Int64(flagPruningKeepEvery, 0, "Define the state number that will be kept. Ignored if pruning is not custom.") + cmd.Flags().Int64(flagPruningSnapshotEvery, 0, "Defines the state that will be snapshot for pruning. Ignored if pruning is not custom.") cmd.Flags().String( FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)", @@ -104,32 +105,15 @@ which accepts a path for the resulting pprof file. cmd.Flags().Bool(FlagInterBlockCache, true, "Enable inter-block caching") cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file") + viper.BindPFlag(flagPruning, cmd.Flags().Lookup(flagPruning)) + viper.BindPFlag(flagPruningKeepEvery, cmd.Flags().Lookup(flagPruningKeepEvery)) + viper.BindPFlag(flagPruningSnapshotEvery, cmd.Flags().Lookup(flagPruningSnapshotEvery)) + // add support for all Tendermint-specific command line options tcmd.AddNodeFlags(cmd) return cmd } -// checkPruningParams checks that the provided pruning params are correct -func checkPruningParams() error { - if !viper.IsSet(flagPruning) && !viper.IsSet(flagPruningKeepEvery) && !viper.IsSet(flagPruningSnapshotEvery) { - return nil - } - - if viper.IsSet(flagPruning) { - if viper.IsSet(flagPruningKeepEvery) || viper.IsSet(flagPruningSnapshotEvery) { - return errPruningWithGranularOptions - } - - return nil - } - - if !(viper.IsSet(flagPruningKeepEvery) && viper.IsSet(flagPruningSnapshotEvery)) { - return errPruningGranularOptions - } - - return nil -} - func startStandAlone(ctx *Context, appCreator AppCreator) error { addr := viper.GetString(flagAddress) home := viper.GetString("home") diff --git a/server/start_test.go b/server/start_test.go index c9c4f61ef640..c1d177c6f480 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -1,6 +1,7 @@ package server import ( + "fmt" "testing" "github.com/spf13/viper" @@ -8,8 +9,6 @@ import ( ) func TestPruningOptions(t *testing.T) { - startCommand := StartCmd(nil, nil) - tests := []struct { name string paramInit func() @@ -17,68 +16,49 @@ func TestPruningOptions(t *testing.T) { expectedErr error }{ { - name: "none set, returns nil and will use default from flags", + name: "default", paramInit: func() {}, returnsErr: false, expectedErr: nil, }, + { + name: "unknown strategy", + paramInit: func() { viper.Set(flagPruning, "unknown") }, + returnsErr: true, + expectedErr: fmt.Errorf("unknown pruning strategy unknown"), + }, { name: "only keep-every provided", paramInit: func() { + viper.Set(flagPruning, "custom") viper.Set(flagPruningKeepEvery, 12345) }, - returnsErr: true, - expectedErr: errPruningGranularOptions, + returnsErr: false, + expectedErr: nil, }, { name: "only snapshot-every provided", paramInit: func() { + viper.Set(flagPruning, "custom") viper.Set(flagPruningSnapshotEvery, 12345) }, returnsErr: true, - expectedErr: errPruningGranularOptions, - }, - { - name: "pruning flag with other granular options 1", - paramInit: func() { - viper.Set(flagPruning, "set") - viper.Set(flagPruningSnapshotEvery, 1234) - }, - returnsErr: true, - expectedErr: errPruningWithGranularOptions, - }, - { - name: "pruning flag with other granular options 2", - paramInit: func() { - viper.Set(flagPruning, "set") - viper.Set(flagPruningKeepEvery, 1234) - }, - returnsErr: true, - expectedErr: errPruningWithGranularOptions, + expectedErr: fmt.Errorf("invalid granular options"), }, { name: "pruning flag with other granular options 3", paramInit: func() { - viper.Set(flagPruning, "set") + viper.Set(flagPruning, "custom") viper.Set(flagPruningKeepEvery, 1234) viper.Set(flagPruningSnapshotEvery, 1234) }, - returnsErr: true, - expectedErr: errPruningWithGranularOptions, - }, - { - name: "only prunning set", - paramInit: func() { - viper.Set(flagPruning, "set") - }, returnsErr: false, expectedErr: nil, }, { - name: "only granular set", + name: "nothing strategy", paramInit: func() { - viper.Set(flagPruningSnapshotEvery, 12345) - viper.Set(flagPruningKeepEvery, 12345) + viper.Set(flagPruning, "nothing") }, returnsErr: false, expectedErr: nil, @@ -90,9 +70,10 @@ func TestPruningOptions(t *testing.T) { t.Run(tt.name, func(t *testing.T) { viper.Reset() + viper.SetDefault(flagPruning, "syncable") + startCommand := StartCmd(nil, nil) tt.paramInit() - - err := startCommand.PreRunE(nil, nil) + err := startCommand.PreRunE(startCommand, nil) if tt.returnsErr { require.EqualError(t, err, tt.expectedErr.Error()) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 189316a7662c..3e595094ccb8 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -1,6 +1,4 @@ -// Package rest provides HTTP types and primitives for REST -// requests validation and responses handling. -package rest +package rest_test import ( "errors" @@ -12,24 +10,27 @@ import ( "strings" "testing" + "github.com/spf13/viper" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" ) func TestBaseReq_Sanitize(t *testing.T) { t.Parallel() - sanitized := BaseReq{ChainID: " test", + sanitized := rest.BaseReq{ChainID: " test", Memo: "memo ", From: " cosmos1cq0sxam6x4l0sv9yz3a2vlqhdhvt2k6jtgcse0 ", Gas: " ", GasAdjustment: " 0.3", }.Sanitize() - require.Equal(t, BaseReq{ChainID: "test", + require.Equal(t, rest.BaseReq{ChainID: "test", Memo: "memo", From: "cosmos1cq0sxam6x4l0sv9yz3a2vlqhdhvt2k6jtgcse0", Gas: "", @@ -44,25 +45,25 @@ func TestBaseReq_ValidateBasic(t *testing.T) { onestake, err := types.ParseDecCoins("1.0stake") require.NoError(t, err) - req1 := NewBaseReq( + req1 := rest.NewBaseReq( fromAddr, "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) - req2 := NewBaseReq( + req2 := rest.NewBaseReq( "", "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) - req3 := NewBaseReq( + req3 := rest.NewBaseReq( fromAddr, "", "", "", "", 0, 0, tenstakes, nil, false, ) - req4 := NewBaseReq( + req4 := rest.NewBaseReq( fromAddr, "", "nonempty", "", "", 0, 0, tenstakes, onestake, false, ) - req5 := NewBaseReq( + req5 := rest.NewBaseReq( fromAddr, "", "nonempty", "", "", 0, 0, types.Coins{}, types.DecCoins{}, false, ) tests := []struct { name string - req BaseReq + req rest.BaseReq w http.ResponseWriter want bool }{ @@ -102,21 +103,21 @@ func TestParseHTTPArgs(t *testing.T) { limit int err bool }{ - {"no params", req0, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, false}, - {"Limit", req1, httptest.NewRecorder(), []string{}, DefaultPage, 5, false}, - {"Page", req2, httptest.NewRecorder(), []string{}, 5, DefaultLimit, false}, + {"no params", req0, httptest.NewRecorder(), []string{}, rest.DefaultPage, rest.DefaultLimit, false}, + {"Limit", req1, httptest.NewRecorder(), []string{}, rest.DefaultPage, 5, false}, + {"Page", req2, httptest.NewRecorder(), []string{}, 5, rest.DefaultLimit, false}, {"Page and limit", req3, httptest.NewRecorder(), []string{}, 5, 5, false}, - {"error page 0", reqE1, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true}, - {"error limit 0", reqE2, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true}, + {"error page 0", reqE1, httptest.NewRecorder(), []string{}, rest.DefaultPage, rest.DefaultLimit, true}, + {"error limit 0", reqE2, httptest.NewRecorder(), []string{}, rest.DefaultPage, rest.DefaultLimit, true}, - {"tags", req4, httptest.NewRecorder(), []string{"foo='faa'"}, DefaultPage, DefaultLimit, false}, - {"tags", reqTxH, httptest.NewRecorder(), []string{"tx.height<=14", "tx.height>=12"}, DefaultPage, DefaultLimit, false}, + {"tags", req4, httptest.NewRecorder(), []string{"foo='faa'"}, rest.DefaultPage, rest.DefaultLimit, false}, + {"tags", reqTxH, httptest.NewRecorder(), []string{"tx.height<=14", "tx.height>=12"}, rest.DefaultPage, rest.DefaultLimit, false}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - tags, page, limit, err := ParseHTTPArgs(tt.req) + tags, page, limit, err := rest.ParseHTTPArgs(tt.req) sort.Strings(tags) @@ -158,7 +159,7 @@ func TestParseQueryHeight(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - cliCtx, ok := ParseQueryHeightOrReturnBadRequest(tt.w, tt.cliCtx, tt.req) + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(tt.w, tt.cliCtx, tt.req) if tt.expectedOk { require.True(t, ok) require.Equal(t, tt.expectedHeight, cliCtx.Height) @@ -185,6 +186,7 @@ func TestProcessPostResponse(t *testing.T) { } // setup + viper.Set(flags.FlagOffline, true) ctx := context.NewCLIContext() height := int64(194423) @@ -205,7 +207,7 @@ func TestProcessPostResponse(t *testing.T) { jsonNoIndent, err := ctx.Codec.MarshalJSON(acc) require.Nil(t, err) - respNoIndent := NewResponseWithHeight(height, jsonNoIndent) + respNoIndent := rest.NewResponseWithHeight(height, jsonNoIndent) expectedNoIndent, err := ctx.Codec.MarshalJSON(respNoIndent) require.Nil(t, err) @@ -215,7 +217,7 @@ func TestProcessPostResponse(t *testing.T) { // check that negative height writes an error w := httptest.NewRecorder() ctx = ctx.WithHeight(-1) - PostProcessResponse(w, ctx, acc) + rest.PostProcessResponse(w, ctx, acc) require.Equal(t, http.StatusInternalServerError, w.Code) // check that height returns expected response @@ -231,21 +233,21 @@ func TestReadRESTReq(t *testing.T) { reqBody := ioutil.NopCloser(strings.NewReader(`{"chain_id":"alessio","memo":"text"}`)) req := &http.Request{Body: reqBody} w := httptest.NewRecorder() - var br BaseReq + var br rest.BaseReq // test OK - ReadRESTReq(w, req, codec.New(), &br) + rest.ReadRESTReq(w, req, codec.New(), &br) res := w.Result() t.Cleanup(func() { res.Body.Close() }) - require.Equal(t, BaseReq{ChainID: "alessio", Memo: "text"}, br) + require.Equal(t, rest.BaseReq{ChainID: "alessio", Memo: "text"}, br) require.Equal(t, http.StatusOK, res.StatusCode) // test non valid JSON reqBody = ioutil.NopCloser(strings.NewReader(`MALFORMED`)) req = &http.Request{Body: reqBody} - br = BaseReq{} + br = rest.BaseReq{} w = httptest.NewRecorder() - ReadRESTReq(w, req, codec.New(), &br) + rest.ReadRESTReq(w, req, codec.New(), &br) require.Equal(t, br, br) res = w.Result() t.Cleanup(func() { res.Body.Close() }) @@ -255,7 +257,7 @@ func TestReadRESTReq(t *testing.T) { func TestWriteSimulationResponse(t *testing.T) { t.Parallel() w := httptest.NewRecorder() - WriteSimulationResponse(w, codec.New(), 10) + rest.WriteSimulationResponse(w, codec.New(), 10) res := w.Result() t.Cleanup(func() { res.Body.Close() }) require.Equal(t, http.StatusOK, res.StatusCode) @@ -268,12 +270,12 @@ func TestWriteSimulationResponse(t *testing.T) { func TestParseUint64OrReturnBadRequest(t *testing.T) { t.Parallel() w := httptest.NewRecorder() - _, ok := ParseUint64OrReturnBadRequest(w, "100") + _, ok := rest.ParseUint64OrReturnBadRequest(w, "100") require.True(t, ok) require.Equal(t, http.StatusOK, w.Result().StatusCode) w = httptest.NewRecorder() - _, ok = ParseUint64OrReturnBadRequest(w, "-100") + _, ok = rest.ParseUint64OrReturnBadRequest(w, "-100") require.False(t, ok) require.Equal(t, http.StatusBadRequest, w.Result().StatusCode) } @@ -281,17 +283,17 @@ func TestParseUint64OrReturnBadRequest(t *testing.T) { func TestParseFloat64OrReturnBadRequest(t *testing.T) { t.Parallel() w := httptest.NewRecorder() - _, ok := ParseFloat64OrReturnBadRequest(w, "100", 0) + _, ok := rest.ParseFloat64OrReturnBadRequest(w, "100", 0) require.True(t, ok) require.Equal(t, http.StatusOK, w.Result().StatusCode) w = httptest.NewRecorder() - _, ok = ParseFloat64OrReturnBadRequest(w, "bad request", 0) + _, ok = rest.ParseFloat64OrReturnBadRequest(w, "bad request", 0) require.False(t, ok) require.Equal(t, http.StatusBadRequest, w.Result().StatusCode) w = httptest.NewRecorder() - ret, ok := ParseFloat64OrReturnBadRequest(w, "", 9.0) + ret, ok := rest.ParseFloat64OrReturnBadRequest(w, "", 9.0) require.Equal(t, float64(9), ret) require.True(t, ok) require.Equal(t, http.StatusOK, w.Result().StatusCode) @@ -299,11 +301,11 @@ func TestParseFloat64OrReturnBadRequest(t *testing.T) { func TestParseQueryParamBool(t *testing.T) { req := httptest.NewRequest("GET", "/target?boolean=true", nil) - require.True(t, ParseQueryParamBool(req, "boolean")) - require.False(t, ParseQueryParamBool(req, "nokey")) + require.True(t, rest.ParseQueryParamBool(req, "boolean")) + require.False(t, rest.ParseQueryParamBool(req, "nokey")) req = httptest.NewRequest("GET", "/target?boolean=false", nil) - require.False(t, ParseQueryParamBool(req, "boolean")) - require.False(t, ParseQueryParamBool(req, "")) + require.False(t, rest.ParseQueryParamBool(req, "boolean")) + require.False(t, rest.ParseQueryParamBool(req, "")) } func TestPostProcessResponseBare(t *testing.T) { @@ -314,7 +316,7 @@ func TestPostProcessResponseBare(t *testing.T) { w := httptest.NewRecorder() bs := []byte("text string") - PostProcessResponseBare(w, ctx, bs) + rest.PostProcessResponseBare(w, ctx, bs) res := w.Result() require.Equal(t, http.StatusOK, res.StatusCode) @@ -333,7 +335,7 @@ func TestPostProcessResponseBare(t *testing.T) { S string `json:"s"` }{X: 10, S: "test"} - PostProcessResponseBare(w, ctx, data) + rest.PostProcessResponseBare(w, ctx, data) res = w.Result() require.Equal(t, http.StatusOK, res.StatusCode) @@ -355,7 +357,7 @@ func TestPostProcessResponseBare(t *testing.T) { S string `json:"s"` }{X: 10, S: "test"} - PostProcessResponseBare(w, ctx, data) + rest.PostProcessResponseBare(w, ctx, data) res = w.Result() require.Equal(t, http.StatusOK, res.StatusCode) @@ -371,7 +373,7 @@ func TestPostProcessResponseBare(t *testing.T) { w = httptest.NewRecorder() data2 := badJSONMarshaller{} - PostProcessResponseBare(w, ctx, data2) + rest.PostProcessResponseBare(w, ctx, data2) res = w.Result() require.Equal(t, http.StatusInternalServerError, res.StatusCode) @@ -401,7 +403,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ // test using regular struct w := httptest.NewRecorder() - PostProcessResponse(w, ctx, obj) + rest.PostProcessResponse(w, ctx, obj) require.Equal(t, http.StatusOK, w.Code, w.Body) resp := w.Result() @@ -421,7 +423,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ // test using marshalled struct w = httptest.NewRecorder() - PostProcessResponse(w, ctx, marshalled) + rest.PostProcessResponse(w, ctx, marshalled) require.Equal(t, http.StatusOK, w.Code, w.Body) resp = w.Result() @@ -452,12 +454,12 @@ func TestCheckErrors(t *testing.T) { wantString string wantStatus int }{ - {"500", CheckInternalServerError, err, true, `{"error":"ERROR"}`, http.StatusInternalServerError}, - {"500 (no error)", CheckInternalServerError, nil, false, ``, http.StatusInternalServerError}, - {"400", CheckBadRequestError, err, true, `{"error":"ERROR"}`, http.StatusBadRequest}, - {"400 (no error)", CheckBadRequestError, nil, false, ``, http.StatusBadRequest}, - {"404", CheckNotFoundError, err, true, `{"error":"ERROR"}`, http.StatusNotFound}, - {"404 (no error)", CheckNotFoundError, nil, false, ``, http.StatusNotFound}, + {"500", rest.CheckInternalServerError, err, true, `{"error":"ERROR"}`, http.StatusInternalServerError}, + {"500 (no error)", rest.CheckInternalServerError, nil, false, ``, http.StatusInternalServerError}, + {"400", rest.CheckBadRequestError, err, true, `{"error":"ERROR"}`, http.StatusBadRequest}, + {"400 (no error)", rest.CheckBadRequestError, nil, false, ``, http.StatusBadRequest}, + {"404", rest.CheckNotFoundError, err, true, `{"error":"ERROR"}`, http.StatusNotFound}, + {"404 (no error)", rest.CheckNotFoundError, nil, false, ``, http.StatusNotFound}, } for _, tt := range tests { diff --git a/x/distribution/client/common/common_test.go b/x/distribution/client/common/common_test.go index 5954f9850742..ea7ed8527280 100644 --- a/x/distribution/client/common/common_test.go +++ b/x/distribution/client/common/common_test.go @@ -3,14 +3,17 @@ package common import ( "testing" + "github.com/spf13/viper" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) func TestQueryDelegationRewardsAddrValidation(t *testing.T) { cdc := codec.New() + viper.Set(flags.FlagOffline, true) ctx := context.NewCLIContext().WithCodec(cdc) type args struct { delAddr string