diff --git a/.golangci.yml b/.golangci.yml index 34738ccf7e6f..1cbfa6a6c097 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -56,6 +56,9 @@ issues: - text: "ST1016:" linters: - stylecheck + - text: "SA1019: codec.LegacyAmino is deprecated" + linters: + - staticcheck max-issues-per-linter: 10000 max-same-issues: 10000 diff --git a/CHANGELOG.md b/CHANGELOG.md index c7bd85ca42d0..cacb1f0b6e71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,10 +34,101 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog +## Unreleased + +## [v0.42.10](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.10) - 2021-09-28 + +### Improvements + +* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. +* (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. +* [\#10211](https://github.com/cosmos/cosmos-sdk/pull/10211) Backport of the mechanism to reject redundant IBC transactions from [ibc-go \#235](https://github.com/cosmos/ibc-go/pull/235). + +### Bug Fixes + +* [\#9969](https://github.com/cosmos/cosmos-sdk/pull/9969) fix: use keyring in config for add-genesis-account cmd. + +### Client Breaking Changes + +* [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height. + +### API Breaking Changes + +* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. + +## [v0.42.9](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.9) - 2021-08-04 + +### Bug Fixes + +* [\#9835](https://github.com/cosmos/cosmos-sdk/pull/9835) Moved capability initialization logic to BeginBlocker to fix nondeterminsim issue mentioned in [\#9800](https://github.com/cosmos/cosmos-sdk/issues/9800). Applications must now include the capability module in their BeginBlocker order before any module that uses capabilities gets run. +* [\#9201](https://github.com/cosmos/cosmos-sdk/pull/9201) Fixed ` init --recover` flag. + +### API Breaking Changes + +* [\#9835](https://github.com/cosmos/cosmos-sdk/pull/9835) The `InitializeAndSeal` API has not changed, however it no longer initializes the in-memory state. `InitMemStore` has been introduced to serve this function, which will be called either in `InitChain` or `BeginBlock` (whichever is first after app start). Nodes may run this version on a network running 0.42.x, however, they must update their app.go files to include the capability module in their begin blockers. + +### Client Breaking Changes + +* [\#9781](https://github.com/cosmos/cosmos-sdk/pull/9781) Improve`withdraw-all-rewards` UX when broadcast mode `async` or `async` is used. + +## [v0.42.8](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.8) - 2021-07-30 + +### Features + +* [\#9750](https://github.com/cosmos/cosmos-sdk/pull/9750) Emit events for tx signature and sequence, so clients can now query txs by signature (`tx.signature=''`) or by address and sequence combo (`tx.acc_seq='/'`). + +### Improvements + +* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12). +* (cli) [\#9717](https://github.com/cosmos/cosmos-sdk/pull/9717) Added CLI flag `--output json/text` to `tx` cli commands. + +### Bug Fixes + +* [\#9766](https://github.com/cosmos/cosmos-sdk/pull/9766) Fix hardcoded ledger signing algorithm on `keys add` command. + +## [v0.42.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.7) - 2021-07-09 + +### Improvements + +* (baseapp) [\#9578](https://github.com/cosmos/cosmos-sdk/pull/9578) Return `Baseapp`'s `trace` value for logging error stack traces. +* (cli) [\#9593](https://github.com/cosmos/cosmos-sdk/pull/9593) Check if chain-id is blank before verifying signatures in multisign and error. + +### Bug Fixes + +* (x/ibc) [\#9640](https://github.com/cosmos/cosmos-sdk/pull/9640) Fix IBC Transfer Ack Success event as it was initially emitting opposite value. +* [\#9645](https://github.com/cosmos/cosmos-sdk/pull/9645) Use correct Prometheus format for metric labels. +* [\#9299](https://github.com/cosmos/cosmos-sdk/pull/9299) Fix `[appd] keys parse cosmos1...` freezing. +* (keyring) [\#9563](https://github.com/cosmos/cosmos-sdk/pull/9563) fix keyring kwallet backend when using with empty wallet. +* (x/capability) [\#9392](https://github.com/cosmos/cosmos-sdk/pull/9392) initialization fix, which fixes the consensus error when using statesync. + + +## [v0.42.6](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.6) - 2021-06-18 + +### Improvements + +* [\#9428](https://github.com/cosmos/cosmos-sdk/pull/9428) Optimize bank InitGenesis. Added `k.initBalances`. +* [\#9429](https://github.com/cosmos/cosmos-sdk/pull/9429) Add `cosmos_sdk_version` to node_info +* [\#9541](https://github.com/cosmos/cosmos-sdk/pull/9541) Bump tendermint dependency to v0.34.11. + +### Bug Fixes + +* [\#9385](https://github.com/cosmos/cosmos-sdk/pull/9385) Fix IBC `query ibc client header` cli command. Support historical queries for query header/node-state commands. +* [\#9401](https://github.com/cosmos/cosmos-sdk/pull/9401) Fixes incorrect export of IBC identifier sequences. Previously, the next identifier sequence for clients/connections/channels was not set during genesis export. This resulted in the next identifiers being generated on the new chain to reuse old identifiers (the sequences began again from 0). +* [\#9408](https://github.com/cosmos/cosmos-sdk/pull/9408) Update simapp to use correct default broadcast mode. +* [\#9513](https://github.com/cosmos/cosmos-sdk/pull/9513) Fixes testnet CLI command. Testnet now updates the supply in genesis. Previously, when using add-genesis-account and testnet together, inconsistent genesis files would be produced, as only add-genesis-account was updating the supply. +* (x/gov) [\#8813](https://github.com/cosmos/cosmos-sdk/pull/8813) fix `GET /cosmos/gov/v1beta1/proposals/{proposal_id}/deposits` to include initial deposit + +### Features + +* [\#9383](https://github.com/cosmos/cosmos-sdk/pull/9383) New CLI command `query ibc-transfer escrow-address ` to get the escrow address for a channel; can be used to then query balance of escrowed tokens +* (baseapp, types) [#\9390](https://github.com/cosmos/cosmos-sdk/pull/9390) Add current block header hash to `Context` +* (store) [\#9403](https://github.com/cosmos/cosmos-sdk/pull/9403) Add `RefundGas` function to `GasMeter` interface + ## [v0.42.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.5) - 2021-05-18 ### Bug Fixes +* [\#9514](https://github.com/cosmos/cosmos-sdk/issues/9514) Fix panic when retrieving the `BlockGasMeter` on `(Re)CheckTx` mode. * [\#9235](https://github.com/cosmos/cosmos-sdk/pull/9235) CreateMembershipProof/CreateNonMembershipProof now returns an error if input key is empty, or input data contains empty key. * [\#9108](https://github.com/cosmos/cosmos-sdk/pull/9108) Fixed the bug with querying multisig account, which is not showing threshold and public_keys. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 46780a54e99b..ee4af7274b62 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -97,7 +97,7 @@ All PRs require two Reviews before merge (except docs changes, or variable name- If you open a PR on the Cosmos SDK, it is mandatory to update the relevant documentation in /docs. - If your change relates to the core SDK (baseapp, store, ...), please update the `docs/basics/`, `docs/core/` and/or `docs/building-modules/` folders. -- If your changes relate to the core of the CLI or Light-client (not specifically to module's CLI/Rest), please modify the `docs/interfaces/` folder. +- If your changes relate to the core of the CLI (not specifically to module's CLI/Rest), please modify the `docs/run-node/` folder. - If your changes relate to a module, please update the module's spec in `x/moduleName/docs/spec/`. ## Forking diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index aee920607c24..9a2a97f9b0af 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,25 +1,15 @@ -# Cosmos SDK v0.42.5 "Stargate" Release Notes +# Cosmos SDK v0.42.10 "Stargate" Release Notes -This release includes various minor bugfixes and improvments, including: +This release includes a new `AnteHandler` that rejects redundant IBC transactions to save relayers fees. This is a backport of [ibc-go \#235](https://github.com/cosmos/ibc-go/pull/235). -- Fix support for building the Cosmos SDK on ARM architectures, -- Fix the `[appd] keys show/list` CLI subcommands for multisigs, -- Internal code performance improvment. +v0.42.10 also includes multiple performance improvements, such as: -It also introduces one new feature: adding the `[appd] config` subcommand back to the SDK. +- improve ABCI performance under concurrent load via [Tendermint v0.34.13](https://github.com/tendermint/tendermint/blob/master/CHANGELOG.md#v03413), +- improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. +- bump IAVL to v0.17.1 which includes performance improvements on a batch load. -See the [Cosmos SDK v0.42.5 milestone](https://github.com/cosmos/cosmos-sdk/milestone/44?closed=1) on our issue tracker for the exhaustive list of all changes. +We fixed the keyring to use pre-configured data for `add-genesis-account` command. -### The `config` Subcommand +Finally, when using the `client.Context`, we modified ABCI queries to use `abci.QueryRequest`'s `Height` field if it is non-zero, otherwise continue using `client.Context`'s height. This is a minor client-breaking change for users of the `client.Context`. -One new feature introduced in the Stargate series was the merging of the two CLI binaries `[appd]` and `[appcli]` into one single application binary. In this process, the `[appcli] config` subcommand, which was used to save client-side configuration into a TOML file, was removed. - -Due to [popular demand](https://github.com/cosmos/cosmos-sdk/issues/8529), we have introduced this feature back to the SDK, under the `[appd] config` subcommand. The functionality is as follows: - -- `[appd] config`: Output all client-side configuration. -- `[appd] config [config-name]`: Get the given configuration (e.g. `keyring-backend` or `node-id`). -- `[appd] config [config-name] [config-value]`: Set and persist the given configuration with the new value. - -All configurations are persisted to the filesystem, under the path `$APP_HOME/config/client.toml`. For the list of all possible client-side configurations, please have a look at this `client.toml` file, as it is heavily commented. - -Environment variables binding to client-side configuration also works. For example, the command `KEYRING_BACKEND=os [appd] tx bank send ...` will bind ENV variable to the `keyring-backend` config. The order or precedence for config is: `flags > env vars > client.toml file`. +See the [Cosmos SDK v0.42.10 milestone](https://github.com/cosmos/cosmos-sdk/milestone/55?closed=1) on our issue tracker for the exhaustive list of all changes. diff --git a/baseapp/abci.go b/baseapp/abci.go index 36c36d1e118b..46e258f48111 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -173,7 +173,19 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg gasMeter = sdk.NewInfiniteGasMeter() } - app.deliverState.ctx = app.deliverState.ctx.WithBlockGasMeter(gasMeter) + // NOTE: header hash is not set in NewContext, so we manually set it here + + app.deliverState.ctx = app.deliverState.ctx. + WithBlockGasMeter(gasMeter). + WithHeaderHash(req.Hash) + + // we also set block gas meter to checkState in case the application needs to + // verify gas consumption during (Re)CheckTx + if app.checkState != nil { + app.checkState.ctx = app.checkState.ctx. + WithBlockGasMeter(gasMeter). + WithHeaderHash(req.Hash) + } if app.beginBlocker != nil { res = app.beginBlocker(app.deliverState.ctx, req) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index a79aed801b6f..f52f377eda30 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -180,6 +180,11 @@ func (app *BaseApp) Logger() log.Logger { return app.logger } +// Trace returns the boolean value for logging error stack traces. +func (app *BaseApp) Trace() bool { + return app.trace +} + // MsgServiceRouter returns the MsgServiceRouter of a BaseApp. func (app *BaseApp) MsgServiceRouter() *MsgServiceRouter { return app.msgServiceRouter } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index b0eace4d3294..37c37fdce2a9 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -950,7 +950,11 @@ func TestCheckTx(t *testing.T) { // If a block is committed, CheckTx state should be reset. header := tmproto.Header{Height: 1} - app.BeginBlock(abci.RequestBeginBlock{Header: header}) + app.BeginBlock(abci.RequestBeginBlock{Header: header, Hash: []byte("hash")}) + + require.NotNil(t, app.checkState.ctx.BlockGasMeter(), "block gas meter should have been set to checkState") + require.NotEmpty(t, app.checkState.ctx.HeaderHash()) + app.EndBlock(abci.RequestEndBlock{}) app.Commit() diff --git a/client/context.go b/client/context.go index cacdb6ee961c..44ccbc259cd5 100644 --- a/client/context.go +++ b/client/context.go @@ -1,6 +1,7 @@ package client import ( + "bufio" "encoding/json" "io" "os" @@ -60,7 +61,10 @@ func (ctx Context) WithKeyring(k keyring.Keyring) Context { // WithInput returns a copy of the context with an updated input. func (ctx Context) WithInput(r io.Reader) Context { - ctx.Input = r + // convert to a bufio.Reader to have a shared buffer between the keyring and the + // the Commands, ensuring a read from one advance the read pointer for the other. + // see https://github.com/cosmos/cosmos-sdk/issues/9566. + ctx.Input = bufio.NewReader(r) return ctx } diff --git a/client/docs/statik/init.go b/client/docs/statik/init.go index 7d91b40fcd37..db70716be44b 100644 --- a/client/docs/statik/init.go +++ b/client/docs/statik/init.go @@ -1,3 +1,3 @@ package statik -//This just for fixing the error in importing empty github.com/cosmos/cosmos-sdk/client/docs/statik +// This just for fixing the error in importing empty github.com/cosmos/cosmos-sdk/client/docs/statik diff --git a/client/flags/flags.go b/client/flags/flags.go index b305412d4667..7d4de556b69c 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -94,6 +94,7 @@ func AddQueryFlagsToCmd(cmd *cobra.Command) { // AddTxFlagsToCmd adds common flags to a module tx command. func AddTxFlagsToCmd(cmd *cobra.Command) { + cmd.Flags().StringP(tmcli.OutputFlag, "o", "json", "Output format (text|json)") cmd.Flags().String(FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used") cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") cmd.Flags().Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)") diff --git a/client/grpc/tmservice/query.pb.go b/client/grpc/tmservice/query.pb.go index 8055c8c162aa..92b24cc3246d 100644 --- a/client/grpc/tmservice/query.pb.go +++ b/client/grpc/tmservice/query.pb.go @@ -688,13 +688,14 @@ func (m *GetNodeInfoResponse) GetApplicationVersion() *VersionInfo { // VersionInfo is the type for the GetNodeInfoResponse message. type VersionInfo struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` - BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"` - GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` - BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` + BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"` + GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` + BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"` + CosmosSdkVersion string `protobuf:"bytes,8,opt,name=cosmos_sdk_version,json=cosmosSdkVersion,proto3" json:"cosmos_sdk_version,omitempty"` } func (m *VersionInfo) Reset() { *m = VersionInfo{} } @@ -779,6 +780,13 @@ func (m *VersionInfo) GetBuildDeps() []*Module { return nil } +func (m *VersionInfo) GetCosmosSdkVersion() string { + if m != nil { + return m.CosmosSdkVersion + } + return "" +} + // Module is the type for VersionInfo type Module struct { // module path @@ -866,74 +874,75 @@ func init() { } var fileDescriptor_40c93fb3ef485c5d = []byte{ - // 1060 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xdc, 0x44, - 0x14, 0xaf, 0xb3, 0x6d, 0x36, 0x79, 0x8b, 0x20, 0x99, 0x84, 0xc6, 0xb1, 0xd2, 0x6d, 0xf0, 0xa1, - 0x4d, 0x88, 0x62, 0x6b, 0xb7, 0x6d, 0xda, 0x43, 0x29, 0x22, 0x04, 0xd2, 0xa8, 0xa5, 0x8a, 0x1c, - 0xc4, 0x01, 0x21, 0x59, 0xde, 0xf5, 0xc4, 0x19, 0x65, 0xd7, 0x33, 0xf5, 0x8c, 0x83, 0x56, 0xa8, - 0x02, 0x71, 0xe2, 0x88, 0xc4, 0x57, 0xe8, 0x85, 0x2f, 0xc0, 0x11, 0x71, 0xe4, 0x58, 0x81, 0x84, - 0x2a, 0x4e, 0x28, 0xe1, 0x53, 0x70, 0x42, 0x9e, 0x19, 0xef, 0xda, 0x4d, 0xd2, 0xdd, 0xcd, 0x01, - 0x89, 0x93, 0x67, 0xde, 0xbf, 0xf9, 0xfd, 0xde, 0xbc, 0xf7, 0x3c, 0xf0, 0x6e, 0x9b, 0xf2, 0x2e, - 0xe5, 0x6e, 0x2b, 0xe0, 0xd8, 0x15, 0x38, 0x0e, 0x71, 0xd2, 0x25, 0xb1, 0x70, 0x8f, 0x1a, 0x2d, - 0x2c, 0x82, 0x86, 0xfb, 0x34, 0xc5, 0x49, 0xcf, 0x61, 0x09, 0x15, 0x14, 0xd5, 0x95, 0xad, 0x93, - 0xd9, 0x3a, 0x03, 0x5b, 0x47, 0xdb, 0x5a, 0xf3, 0x11, 0x8d, 0xa8, 0x34, 0x75, 0xb3, 0x95, 0xf2, - 0xb2, 0x16, 0x23, 0x4a, 0xa3, 0x0e, 0x76, 0xe5, 0xae, 0x95, 0xee, 0xbb, 0x41, 0xac, 0x03, 0x5a, - 0x4b, 0x5a, 0x15, 0x30, 0xe2, 0x06, 0x71, 0x4c, 0x45, 0x20, 0x08, 0x8d, 0xb9, 0xd6, 0x5a, 0x05, - 0x38, 0xac, 0xc9, 0x5c, 0xd1, 0x63, 0x38, 0xd7, 0x2d, 0x15, 0x74, 0x52, 0xee, 0xb6, 0x3a, 0xb4, - 0x7d, 0x78, 0xae, 0xb6, 0xe8, 0x5b, 0xa2, 0x2c, 0xf9, 0xf5, 0xd9, 0xb2, 0x20, 0x22, 0xb1, 0x04, - 0xa1, 0x6c, 0xed, 0x6f, 0x0c, 0xa8, 0x6f, 0x63, 0xf1, 0x59, 0xd0, 0x21, 0x61, 0x20, 0x68, 0xb2, - 0x87, 0xc5, 0x66, 0xef, 0x21, 0x26, 0xd1, 0x81, 0xf0, 0xf0, 0xd3, 0x14, 0x73, 0x81, 0xae, 0xc2, - 0xe4, 0x81, 0x14, 0x98, 0xc6, 0xb2, 0xb1, 0x52, 0xf1, 0xf4, 0x0e, 0x7d, 0x0c, 0x30, 0x08, 0x67, - 0x4e, 0x2c, 0x1b, 0x2b, 0xb5, 0xe6, 0x0d, 0xa7, 0x98, 0x42, 0x95, 0x5b, 0x7d, 0xb6, 0xb3, 0x1b, - 0x44, 0x58, 0xc7, 0xf4, 0x0a, 0x9e, 0xf6, 0x4b, 0x03, 0xae, 0x9f, 0x0b, 0x81, 0x33, 0x1a, 0x73, - 0x8c, 0xde, 0x81, 0x37, 0x24, 0x7f, 0xbf, 0x84, 0xa4, 0x26, 0x65, 0xca, 0x14, 0xed, 0x00, 0x1c, - 0xe5, 0x21, 0xb8, 0x39, 0xb1, 0x5c, 0x59, 0xa9, 0x35, 0x57, 0x9d, 0xd7, 0xdf, 0xa8, 0xd3, 0x3f, - 0xd4, 0x2b, 0x38, 0xa3, 0xed, 0x12, 0xb3, 0x8a, 0x64, 0x76, 0x73, 0x28, 0x33, 0x05, 0xb5, 0x44, - 0x6d, 0x1f, 0x96, 0xb6, 0xb1, 0x78, 0x1c, 0x08, 0xcc, 0x4b, 0xfc, 0xf2, 0xd4, 0x96, 0x53, 0x68, - 0x5c, 0x38, 0x85, 0x7f, 0x18, 0x70, 0xed, 0x9c, 0x83, 0xfe, 0xdf, 0x09, 0x7c, 0x6e, 0xc0, 0x74, - 0xff, 0x08, 0x64, 0x42, 0x35, 0x08, 0xc3, 0x04, 0x73, 0x2e, 0xf1, 0x4f, 0x7b, 0xf9, 0x16, 0xad, - 0x43, 0x95, 0xa5, 0x2d, 0xff, 0x10, 0xf7, 0x74, 0x21, 0xce, 0x3b, 0xaa, 0xf5, 0x9c, 0xbc, 0x2b, - 0x9d, 0x0f, 0xe2, 0x9e, 0x37, 0xc9, 0xd2, 0xd6, 0x23, 0xdc, 0xcb, 0xb2, 0x71, 0x44, 0x05, 0x89, - 0x23, 0x9f, 0xd1, 0x2f, 0x71, 0x22, 0x11, 0x56, 0xbc, 0x9a, 0x92, 0xed, 0x66, 0x22, 0xb4, 0x06, - 0xb3, 0x2c, 0xa1, 0x8c, 0x72, 0x9c, 0xf8, 0x2c, 0x21, 0x34, 0x21, 0xa2, 0x67, 0x5e, 0x96, 0x76, - 0x33, 0xb9, 0x62, 0x57, 0xcb, 0xed, 0x06, 0x2c, 0x6c, 0x63, 0xb1, 0x99, 0x25, 0x73, 0xc4, 0xee, - 0xb1, 0xbf, 0x06, 0xf3, 0xb4, 0x8b, 0xbe, 0xac, 0xdb, 0x30, 0xa5, 0x2e, 0x8b, 0x84, 0xba, 0x28, - 0x16, 0x8b, 0xb9, 0x57, 0xbd, 0x2e, 0x5d, 0x77, 0xb6, 0xbc, 0xaa, 0x34, 0xdd, 0x09, 0xd1, 0x3a, - 0x5c, 0x91, 0x4b, 0x9d, 0x81, 0x85, 0x73, 0x5c, 0x3c, 0x65, 0x65, 0x2f, 0xc0, 0xdb, 0xfd, 0x92, - 0x51, 0x0a, 0x85, 0xd8, 0x7e, 0x06, 0x57, 0x5f, 0x55, 0xfc, 0x97, 0xb8, 0xe6, 0x60, 0x76, 0x1b, - 0x8b, 0xbd, 0x5e, 0xdc, 0x26, 0x71, 0x94, 0x63, 0x72, 0x00, 0x15, 0x85, 0x1a, 0x8f, 0x09, 0x55, - 0xae, 0x44, 0x12, 0xce, 0x94, 0x97, 0x6f, 0xed, 0x79, 0x69, 0xff, 0x84, 0x86, 0x78, 0x27, 0xde, - 0xa7, 0x79, 0x94, 0x5f, 0x0c, 0x98, 0x2b, 0x89, 0x75, 0x9c, 0x47, 0x30, 0x1b, 0xe2, 0xfd, 0x20, - 0xed, 0x08, 0x3f, 0xa6, 0x21, 0xf6, 0x49, 0xbc, 0x4f, 0x35, 0xc1, 0xeb, 0x45, 0xb4, 0xac, 0xc9, - 0x9c, 0x2d, 0x65, 0xd8, 0x8f, 0xf1, 0x56, 0x58, 0x16, 0xa0, 0x2f, 0x60, 0x2e, 0x60, 0xac, 0x43, - 0xda, 0xb2, 0x82, 0xfd, 0x23, 0x9c, 0xf0, 0xc1, 0x7c, 0x5c, 0x1b, 0xda, 0x4f, 0xca, 0x5c, 0x86, - 0x46, 0x85, 0x38, 0x5a, 0x6e, 0xff, 0x63, 0x40, 0xad, 0x60, 0x83, 0x10, 0x5c, 0x8e, 0x83, 0x2e, - 0xd6, 0xfd, 0x20, 0xd7, 0x68, 0x11, 0xa6, 0x02, 0xc6, 0x7c, 0x29, 0x9f, 0xd0, 0x7d, 0xc2, 0xd8, - 0x93, 0x4c, 0x65, 0x42, 0x35, 0x07, 0x54, 0x51, 0x1a, 0xbd, 0x45, 0xd7, 0x00, 0x22, 0x22, 0xfc, - 0x36, 0xed, 0x76, 0x89, 0x90, 0x85, 0x3e, 0xed, 0x4d, 0x47, 0x44, 0x7c, 0x28, 0x05, 0x99, 0xba, - 0x95, 0x92, 0x4e, 0xe8, 0x8b, 0x20, 0xe2, 0xe6, 0x15, 0xa5, 0x96, 0x92, 0x4f, 0x83, 0x88, 0x4b, - 0x6f, 0xda, 0xe7, 0x3a, 0xa9, 0xbd, 0xa9, 0x46, 0x8a, 0x3e, 0xca, 0xbd, 0x43, 0xcc, 0xb8, 0x59, - 0x95, 0xa3, 0xe5, 0xc6, 0xb0, 0x54, 0x7c, 0x42, 0xc3, 0xb4, 0x83, 0xf5, 0x29, 0x5b, 0x98, 0x71, - 0xfb, 0x21, 0x4c, 0x2a, 0x61, 0x46, 0x9b, 0x05, 0xe2, 0x20, 0xa7, 0x9d, 0xad, 0x8b, 0xdc, 0x26, - 0xca, 0xdc, 0x66, 0xa0, 0xc2, 0xd3, 0xae, 0x66, 0x9c, 0x2d, 0x9b, 0xdf, 0x4d, 0x43, 0x75, 0x0f, - 0x27, 0x47, 0xa4, 0x8d, 0xd1, 0x8f, 0x06, 0xd4, 0x0a, 0x55, 0x81, 0x9a, 0xc3, 0x80, 0x9d, 0xae, - 0x2c, 0xeb, 0xd6, 0x58, 0x3e, 0xaa, 0xec, 0xec, 0xc6, 0xb7, 0xbf, 0xff, 0xfd, 0xc3, 0xc4, 0x1a, - 0x5a, 0x75, 0x87, 0xbc, 0x51, 0xfa, 0x45, 0x89, 0x9e, 0x1b, 0x00, 0x83, 0x46, 0x40, 0x8d, 0x11, - 0x8e, 0x2d, 0x77, 0x92, 0xd5, 0x1c, 0xc7, 0x45, 0x03, 0x75, 0x25, 0xd0, 0x55, 0x74, 0x73, 0x18, - 0x50, 0xdd, 0x7e, 0xe8, 0x27, 0x03, 0xde, 0x2c, 0xcf, 0x10, 0x74, 0x67, 0x84, 0x73, 0x4f, 0x0f, - 0x23, 0x6b, 0x63, 0x5c, 0x37, 0x0d, 0xf9, 0x8e, 0x84, 0xec, 0xa2, 0xf5, 0x61, 0x90, 0xe5, 0xd0, - 0xe1, 0x6e, 0x47, 0xc6, 0x40, 0x3f, 0x1b, 0x30, 0xf3, 0xea, 0x58, 0x46, 0x77, 0x47, 0xc0, 0x70, - 0xd6, 0xec, 0xb7, 0xee, 0x8d, 0xef, 0xa8, 0xe1, 0xdf, 0x95, 0xf0, 0x1b, 0xc8, 0x1d, 0x11, 0xfe, - 0x57, 0xea, 0xaf, 0xf2, 0x0c, 0xfd, 0x66, 0x14, 0xc6, 0x7a, 0xf1, 0x25, 0x80, 0xee, 0x8f, 0x9c, - 0xc9, 0x33, 0x5e, 0x2a, 0xd6, 0x7b, 0x17, 0xf4, 0xd6, 0x7c, 0xee, 0x4b, 0x3e, 0x1b, 0xe8, 0xf6, - 0x30, 0x3e, 0x83, 0x47, 0x04, 0x16, 0xfd, 0x5b, 0xf9, 0xd3, 0x90, 0xff, 0xd7, 0xb3, 0x5e, 0x88, - 0xe8, 0xc1, 0x08, 0xc0, 0x5e, 0xf3, 0xba, 0xb5, 0xde, 0xbf, 0xb0, 0xbf, 0xa6, 0xf6, 0x40, 0x52, - 0xbb, 0x87, 0x36, 0xc6, 0xa3, 0x96, 0xdf, 0xd8, 0xe6, 0xe3, 0x5f, 0x8f, 0xeb, 0xc6, 0x8b, 0xe3, - 0xba, 0xf1, 0xd7, 0x71, 0xdd, 0xf8, 0xfe, 0xa4, 0x7e, 0xe9, 0xc5, 0x49, 0xfd, 0xd2, 0xcb, 0x93, - 0xfa, 0xa5, 0xcf, 0x9b, 0x11, 0x11, 0x07, 0x69, 0xcb, 0x69, 0xd3, 0x6e, 0x1e, 0x5b, 0x7d, 0xd6, - 0x79, 0x78, 0xe8, 0xb6, 0x3b, 0x04, 0xc7, 0xc2, 0x8d, 0x12, 0xd6, 0x76, 0x45, 0x97, 0xab, 0x61, - 0xd6, 0x9a, 0x94, 0xef, 0x9d, 0x5b, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x08, 0x32, 0x9c, 0x36, - 0xf7, 0x0c, 0x00, 0x00, + // 1081 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x6f, 0xdc, 0x44, + 0x18, 0x8e, 0x77, 0xdb, 0x6c, 0xf2, 0x2e, 0x82, 0x64, 0x12, 0x1a, 0xc7, 0x4a, 0xb7, 0x61, 0x0f, + 0x6d, 0x42, 0x88, 0xad, 0xdd, 0xb6, 0x69, 0x0f, 0xa5, 0x88, 0x10, 0x48, 0xa3, 0x96, 0x2a, 0x72, + 0x10, 0x07, 0x84, 0x64, 0x79, 0xd7, 0x13, 0x67, 0x94, 0x5d, 0xcf, 0xd4, 0x33, 0x0e, 0x5a, 0xa1, + 0x0a, 0xc4, 0x89, 0x23, 0x12, 0x7f, 0xa1, 0x07, 0xf8, 0x03, 0x1c, 0x11, 0x47, 0x8e, 0x15, 0x48, + 0xa8, 0xe2, 0x84, 0x12, 0x7e, 0x08, 0xf2, 0xcc, 0x78, 0xd7, 0x6e, 0x92, 0xee, 0x6e, 0x0e, 0x48, + 0x3d, 0x79, 0xe6, 0xfd, 0x9a, 0xe7, 0x79, 0x66, 0xde, 0xf1, 0xc0, 0xbb, 0x6d, 0xca, 0xbb, 0x94, + 0x3b, 0x2d, 0x9f, 0x63, 0x47, 0xe0, 0x28, 0xc0, 0x71, 0x97, 0x44, 0xc2, 0x39, 0x6a, 0xb4, 0xb0, + 0xf0, 0x1b, 0xce, 0x93, 0x04, 0xc7, 0x3d, 0x9b, 0xc5, 0x54, 0x50, 0x54, 0x53, 0xb1, 0x76, 0x1a, + 0x6b, 0x0f, 0x62, 0x6d, 0x1d, 0x6b, 0xcd, 0x87, 0x34, 0xa4, 0x32, 0xd4, 0x49, 0x47, 0x2a, 0xcb, + 0x5a, 0x0c, 0x29, 0x0d, 0x3b, 0xd8, 0x91, 0xb3, 0x56, 0xb2, 0xef, 0xf8, 0x91, 0x2e, 0x68, 0x2d, + 0x69, 0x97, 0xcf, 0x88, 0xe3, 0x47, 0x11, 0x15, 0xbe, 0x20, 0x34, 0xe2, 0xda, 0x6b, 0xe5, 0xe0, + 0xb0, 0x26, 0x73, 0x44, 0x8f, 0xe1, 0xcc, 0xb7, 0x94, 0xf3, 0x49, 0xbb, 0xd3, 0xea, 0xd0, 0xf6, + 0xe1, 0xb9, 0xde, 0x7c, 0x6e, 0x81, 0xb2, 0xe4, 0xd7, 0x67, 0xcb, 0xfc, 0x90, 0x44, 0x12, 0x84, + 0x8a, 0xad, 0x7f, 0x6b, 0x40, 0x6d, 0x1b, 0x8b, 0xcf, 0xfd, 0x0e, 0x09, 0x7c, 0x41, 0xe3, 0x3d, + 0x2c, 0x36, 0x7b, 0x0f, 0x30, 0x09, 0x0f, 0x84, 0x8b, 0x9f, 0x24, 0x98, 0x0b, 0x74, 0x05, 0x26, + 0x0f, 0xa4, 0xc1, 0x34, 0x96, 0x8d, 0x95, 0xb2, 0xab, 0x67, 0xe8, 0x13, 0x80, 0x41, 0x39, 0xb3, + 0xb4, 0x6c, 0xac, 0x54, 0x9b, 0xd7, 0xed, 0xbc, 0x84, 0x4a, 0x5b, 0xbd, 0xb6, 0xbd, 0xeb, 0x87, + 0x58, 0xd7, 0x74, 0x73, 0x99, 0xf5, 0x17, 0x06, 0x5c, 0x3b, 0x17, 0x02, 0x67, 0x34, 0xe2, 0x18, + 0xbd, 0x03, 0x6f, 0x48, 0xfe, 0x5e, 0x01, 0x49, 0x55, 0xda, 0x54, 0x28, 0xda, 0x01, 0x38, 0xca, + 0x4a, 0x70, 0xb3, 0xb4, 0x5c, 0x5e, 0xa9, 0x36, 0x57, 0xed, 0x57, 0xef, 0xa8, 0xdd, 0x5f, 0xd4, + 0xcd, 0x25, 0xa3, 0xed, 0x02, 0xb3, 0xb2, 0x64, 0x76, 0x63, 0x28, 0x33, 0x05, 0xb5, 0x40, 0x6d, + 0x1f, 0x96, 0xb6, 0xb1, 0x78, 0xe4, 0x0b, 0xcc, 0x0b, 0xfc, 0x32, 0x69, 0x8b, 0x12, 0x1a, 0x17, + 0x96, 0xf0, 0x2f, 0x03, 0xae, 0x9e, 0xb3, 0xd0, 0xeb, 0x2d, 0xe0, 0x33, 0x03, 0xa6, 0xfb, 0x4b, + 0x20, 0x13, 0x2a, 0x7e, 0x10, 0xc4, 0x98, 0x73, 0x89, 0x7f, 0xda, 0xcd, 0xa6, 0x68, 0x1d, 0x2a, + 0x2c, 0x69, 0x79, 0x87, 0xb8, 0xa7, 0x0f, 0xe2, 0xbc, 0xad, 0x5a, 0xcf, 0xce, 0xba, 0xd2, 0xfe, + 0x30, 0xea, 0xb9, 0x93, 0x2c, 0x69, 0x3d, 0xc4, 0xbd, 0x54, 0x8d, 0x23, 0x2a, 0x48, 0x14, 0x7a, + 0x8c, 0x7e, 0x85, 0x63, 0x89, 0xb0, 0xec, 0x56, 0x95, 0x6d, 0x37, 0x35, 0xa1, 0x35, 0x98, 0x65, + 0x31, 0x65, 0x94, 0xe3, 0xd8, 0x63, 0x31, 0xa1, 0x31, 0x11, 0x3d, 0xf3, 0x92, 0x8c, 0x9b, 0xc9, + 0x1c, 0xbb, 0xda, 0x5e, 0x6f, 0xc0, 0xc2, 0x36, 0x16, 0x9b, 0xa9, 0x98, 0x23, 0x76, 0x4f, 0xfd, + 0x1b, 0x30, 0x4f, 0xa7, 0xe8, 0xcd, 0xba, 0x05, 0x53, 0x6a, 0xb3, 0x48, 0xa0, 0x0f, 0xc5, 0x62, + 0x5e, 0x7b, 0xd5, 0xeb, 0x32, 0x75, 0x67, 0xcb, 0xad, 0xc8, 0xd0, 0x9d, 0x00, 0xad, 0xc3, 0x65, + 0x39, 0xd4, 0x0a, 0x2c, 0x9c, 0x93, 0xe2, 0xaa, 0xa8, 0xfa, 0x02, 0xbc, 0xdd, 0x3f, 0x32, 0xca, + 0xa1, 0x10, 0xd7, 0x9f, 0xc2, 0x95, 0x97, 0x1d, 0xff, 0x27, 0xae, 0x39, 0x98, 0xdd, 0xc6, 0x62, + 0xaf, 0x17, 0xb5, 0x49, 0x14, 0x66, 0x98, 0x6c, 0x40, 0x79, 0xa3, 0xc6, 0x63, 0x42, 0x85, 0x2b, + 0x93, 0x84, 0x33, 0xe5, 0x66, 0xd3, 0xfa, 0xbc, 0x8c, 0x7f, 0x4c, 0x03, 0xbc, 0x13, 0xed, 0xd3, + 0xac, 0xca, 0x6f, 0x06, 0xcc, 0x15, 0xcc, 0xba, 0xce, 0x43, 0x98, 0x0d, 0xf0, 0xbe, 0x9f, 0x74, + 0x84, 0x17, 0xd1, 0x00, 0x7b, 0x24, 0xda, 0xa7, 0x9a, 0xe0, 0xb5, 0x3c, 0x5a, 0xd6, 0x64, 0xf6, + 0x96, 0x0a, 0xec, 0xd7, 0x78, 0x2b, 0x28, 0x1a, 0xd0, 0x97, 0x30, 0xe7, 0x33, 0xd6, 0x21, 0x6d, + 0x79, 0x82, 0xbd, 0x23, 0x1c, 0xf3, 0xc1, 0xfd, 0xb8, 0x36, 0xb4, 0x9f, 0x54, 0xb8, 0x2c, 0x8d, + 0x72, 0x75, 0xb4, 0xbd, 0xfe, 0x53, 0x09, 0xaa, 0xb9, 0x18, 0x84, 0xe0, 0x52, 0xe4, 0x77, 0xb1, + 0xee, 0x07, 0x39, 0x46, 0x8b, 0x30, 0xe5, 0x33, 0xe6, 0x49, 0x7b, 0x49, 0xf7, 0x09, 0x63, 0x8f, + 0x53, 0x97, 0x09, 0x95, 0x0c, 0x50, 0x59, 0x79, 0xf4, 0x14, 0x5d, 0x05, 0x08, 0x89, 0xf0, 0xda, + 0xb4, 0xdb, 0x25, 0x42, 0x1e, 0xf4, 0x69, 0x77, 0x3a, 0x24, 0xe2, 0x23, 0x69, 0x48, 0xdd, 0xad, + 0x84, 0x74, 0x02, 0x4f, 0xf8, 0x21, 0x37, 0x2f, 0x2b, 0xb7, 0xb4, 0x7c, 0xe6, 0x87, 0x5c, 0x66, + 0xd3, 0x3e, 0xd7, 0x49, 0x9d, 0x4d, 0x35, 0x52, 0xf4, 0x71, 0x96, 0x1d, 0x60, 0xc6, 0xcd, 0x8a, + 0xbc, 0x5a, 0xae, 0x0f, 0x93, 0xe2, 0x53, 0x1a, 0x24, 0x1d, 0xac, 0x57, 0xd9, 0xc2, 0x8c, 0xa3, + 0xf7, 0x00, 0xa9, 0x1c, 0x8f, 0x07, 0x87, 0xfd, 0xd5, 0xa6, 0xe4, 0x6a, 0x33, 0xca, 0xb3, 0x17, + 0x1c, 0x66, 0x52, 0x3d, 0x80, 0x49, 0x55, 0x22, 0x15, 0x89, 0xf9, 0xe2, 0x20, 0x13, 0x29, 0x1d, + 0xe7, 0x95, 0x28, 0x15, 0x95, 0x98, 0x81, 0x32, 0x4f, 0xba, 0x5a, 0x9f, 0x74, 0xd8, 0xfc, 0x7e, + 0x1a, 0x2a, 0x7b, 0x38, 0x3e, 0x22, 0x6d, 0x8c, 0x7e, 0x36, 0xa0, 0x9a, 0x3b, 0x43, 0xa8, 0x39, + 0x8c, 0xc6, 0xe9, 0x73, 0x68, 0xdd, 0x1c, 0x2b, 0x47, 0x1d, 0xd2, 0x7a, 0xe3, 0xbb, 0x3f, 0xff, + 0xfd, 0xb1, 0xb4, 0x86, 0x56, 0x9d, 0x21, 0x2f, 0x9a, 0xfe, 0x11, 0x46, 0xcf, 0x0c, 0x80, 0x41, + 0xdb, 0xa0, 0xc6, 0x08, 0xcb, 0x16, 0xfb, 0xce, 0x6a, 0x8e, 0x93, 0xa2, 0x81, 0x3a, 0x12, 0xe8, + 0x2a, 0xba, 0x31, 0x0c, 0xa8, 0x6e, 0x56, 0xf4, 0x8b, 0x01, 0x6f, 0x16, 0x6f, 0x1c, 0x74, 0x7b, + 0x84, 0x75, 0x4f, 0x5f, 0x5d, 0xd6, 0xc6, 0xb8, 0x69, 0x1a, 0xf2, 0x6d, 0x09, 0xd9, 0x41, 0xeb, + 0xc3, 0x20, 0xcb, 0x2b, 0x8a, 0x3b, 0x1d, 0x59, 0x03, 0xfd, 0x6a, 0xc0, 0xcc, 0xcb, 0x97, 0x38, + 0xba, 0x33, 0x02, 0x86, 0xb3, 0xfe, 0x14, 0xd6, 0xdd, 0xf1, 0x13, 0x35, 0xfc, 0x3b, 0x12, 0x7e, + 0x03, 0x39, 0x23, 0xc2, 0xff, 0x5a, 0xfd, 0x83, 0x9e, 0xa2, 0x3f, 0x8c, 0xdc, 0x4f, 0x20, 0xff, + 0x6e, 0x40, 0xf7, 0x46, 0x56, 0xf2, 0x8c, 0x77, 0x8d, 0xf5, 0xfe, 0x05, 0xb3, 0x35, 0x9f, 0x7b, + 0x92, 0xcf, 0x06, 0xba, 0x35, 0x8c, 0xcf, 0xe0, 0xc9, 0x81, 0x45, 0x7f, 0x57, 0xfe, 0x36, 0xe4, + 0xdf, 0xf8, 0xac, 0xf7, 0x24, 0xba, 0x3f, 0x02, 0xb0, 0x57, 0xbc, 0x85, 0xad, 0x0f, 0x2e, 0x9c, + 0xaf, 0xa9, 0xdd, 0x97, 0xd4, 0xee, 0xa2, 0x8d, 0xf1, 0xa8, 0x65, 0x3b, 0xb6, 0xf9, 0xe8, 0xf7, + 0xe3, 0x9a, 0xf1, 0xfc, 0xb8, 0x66, 0xfc, 0x73, 0x5c, 0x33, 0x7e, 0x38, 0xa9, 0x4d, 0x3c, 0x3f, + 0xa9, 0x4d, 0xbc, 0x38, 0xa9, 0x4d, 0x7c, 0xd1, 0x0c, 0x89, 0x38, 0x48, 0x5a, 0x76, 0x9b, 0x76, + 0xb3, 0xda, 0xea, 0xb3, 0xce, 0x83, 0x43, 0xa7, 0xdd, 0x21, 0x38, 0x12, 0x4e, 0x18, 0xb3, 0xb6, + 0x23, 0xba, 0x5c, 0x5d, 0x66, 0xad, 0x49, 0xf9, 0x3a, 0xba, 0xf9, 0x5f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x9d, 0x37, 0x87, 0xe4, 0x25, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1734,6 +1743,13 @@ func (m *VersionInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CosmosSdkVersion) > 0 { + i -= len(m.CosmosSdkVersion) + copy(dAtA[i:], m.CosmosSdkVersion) + i = encodeVarintQuery(dAtA, i, uint64(len(m.CosmosSdkVersion))) + i-- + dAtA[i] = 0x42 + } if len(m.BuildDeps) > 0 { for iNdEx := len(m.BuildDeps) - 1; iNdEx >= 0; iNdEx-- { { @@ -2082,6 +2098,10 @@ func (m *VersionInfo) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } + l = len(m.CosmosSdkVersion) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } return n } @@ -3647,6 +3667,38 @@ func (m *VersionInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CosmosSdkVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CosmosSdkVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/client/grpc/tmservice/service.go b/client/grpc/tmservice/service.go index 58d44af579cc..34378d9ef128 100644 --- a/client/grpc/tmservice/service.go +++ b/client/grpc/tmservice/service.go @@ -196,13 +196,14 @@ func (s queryServer) GetNodeInfo(ctx context.Context, req *GetNodeInfoRequest) ( resp := GetNodeInfoResponse{ DefaultNodeInfo: protoNodeInfo, ApplicationVersion: &VersionInfo{ - AppName: nodeInfo.AppName, - Name: nodeInfo.Name, - GitCommit: nodeInfo.GitCommit, - GoVersion: nodeInfo.GoVersion, - Version: nodeInfo.Version, - BuildTags: nodeInfo.BuildTags, - BuildDeps: deps, + AppName: nodeInfo.AppName, + Name: nodeInfo.Name, + GitCommit: nodeInfo.GitCommit, + GoVersion: nodeInfo.GoVersion, + Version: nodeInfo.Version, + BuildTags: nodeInfo.BuildTags, + BuildDeps: deps, + CosmosSdkVersion: nodeInfo.CosmosSdkVersion, }, } return &resp, nil diff --git a/client/grpc_query.go b/client/grpc_query.go index 011523944c54..cbaba73caa2a 100644 --- a/client/grpc_query.go +++ b/client/grpc_query.go @@ -112,8 +112,9 @@ func RunGRPCQuery(ctx Context, grpcCtx gocontext.Context, method string, req int } abciReq := abci.RequestQuery{ - Path: method, - Data: reqBz, + Path: method, + Data: reqBz, + Height: ctx.Height, } abciRes, err := ctx.QueryABCI(abciReq) diff --git a/client/keys/add.go b/client/keys/add.go index 979983b9bdfe..1e8783550098 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -83,12 +83,12 @@ the flag --nosort is set. } func runAddCmdPrepare(cmd *cobra.Command, args []string) error { - buf := bufio.NewReader(cmd.InOrStdin()) clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } + buf := bufio.NewReader(clientCtx.Input) return RunAddCmd(clientCtx, cmd, args, buf) } @@ -200,8 +200,8 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf // If we're using ledger, only thing we need is the path and the bech32 prefix. if useLedger { bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() - info, err := kb.SaveLedgerKey(name, hd.Secp256k1, bech32PrefixAccAddr, coinType, account, index) + info, err := kb.SaveLedgerKey(name, algo, bech32PrefixAccAddr, coinType, account, index) if err != nil { return err } diff --git a/client/keys/add_test.go b/client/keys/add_test.go index aa6f68876a2e..6c8af3867da6 100644 --- a/client/keys/add_test.go +++ b/client/keys/add_test.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" + bip39 "github.com/cosmos/go-bip39" ) func Test_runAddCmdBasic(t *testing.T) { @@ -27,7 +28,7 @@ func Test_runAddCmdBasic(t *testing.T) { kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn) require.NoError(t, err) - clientCtx := client.Context{}.WithKeyringDir(kbHome) + clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn) ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) t.Cleanup(func() { @@ -114,3 +115,47 @@ func Test_runAddCmdBasic(t *testing.T) { mockIn.Reset("\n" + password + "\n" + "fail" + "\n") require.Error(t, cmd.ExecuteContext(ctx)) } + +func TestAddRecoverFileBackend(t *testing.T) { + cmd := AddKeyCommand() + cmd.Flags().AddFlagSet(Commands("home").PersistentFlags()) + + mockIn := testutil.ApplyMockIODiscardOutErr(cmd) + kbHome := t.TempDir() + + clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + cmd.SetArgs([]string{ + "keyname1", + fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome), + fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText), + fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)), + fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendFile), + fmt.Sprintf("--%s", flagRecover), + }) + + keyringPassword := "12345678" + + entropySeed, err := bip39.NewEntropy(mnemonicEntropySize) + require.NoError(t, err) + + mnemonic, err := bip39.NewMnemonic(entropySeed) + require.NoError(t, err) + + mockIn.Reset(fmt.Sprintf("%s\n%s\n%s\n", mnemonic, keyringPassword, keyringPassword)) + require.NoError(t, cmd.ExecuteContext(ctx)) + + kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendFile, kbHome, mockIn) + require.NoError(t, err) + + t.Cleanup(func() { + mockIn.Reset(fmt.Sprintf("%s\n%s\n", keyringPassword, keyringPassword)) + _ = kb.Delete("keyname1") + }) + + mockIn.Reset(fmt.Sprintf("%s\n%s\n", keyringPassword, keyringPassword)) + info, err := kb.Key("keyname1") + require.NoError(t, err) + require.Equal(t, "keyname1", info.GetName()) +} diff --git a/client/keys/export.go b/client/keys/export.go index 7e9cb88ed633..13491b5e839a 100644 --- a/client/keys/export.go +++ b/client/keys/export.go @@ -31,11 +31,11 @@ FULLY AWARE OF THE RISKS. If you are unsure, you may want to do some research and export your keys in ASCII-armored encrypted format.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - buf := bufio.NewReader(cmd.InOrStdin()) clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } + buf := bufio.NewReader(clientCtx.Input) unarmored, _ := cmd.Flags().GetBool(flagUnarmoredHex) unsafe, _ := cmd.Flags().GetBool(flagUnsafe) diff --git a/client/keys/export_test.go b/client/keys/export_test.go index b207a71bb159..7b07bbc6dbd5 100644 --- a/client/keys/export_test.go +++ b/client/keys/export_test.go @@ -1,6 +1,7 @@ package keys import ( + "bufio" "context" "fmt" "testing" @@ -17,55 +18,95 @@ import ( ) func Test_runExportCmd(t *testing.T) { - cmd := ExportKeyCommand() - cmd.Flags().AddFlagSet(Commands("home").PersistentFlags()) - mockIn := testutil.ApplyMockIODiscardOutErr(cmd) - - // Now add a temporary keybase - kbHome := t.TempDir() - - // create a key - kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn) - require.NoError(t, err) - t.Cleanup(func() { - kb.Delete("keyname1") // nolint:errcheck - }) - - path := sdk.GetConfig().GetFullFundraiserPath() - _, err = kb.NewAccount("keyname1", testutil.TestMnemonic, "", path, hd.Secp256k1) - require.NoError(t, err) - - // Now enter password - args := []string{ - "keyname1", - fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome), - fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), + testCases := []struct { + name string + keyringBackend string + extraArgs []string + userInput string + mustFail bool + expectedOutput string + }{ + { + name: "--unsafe only must fail", + keyringBackend: keyring.BackendTest, + extraArgs: []string{"--unsafe"}, + mustFail: true, + }, + { + name: "--unarmored-hex must fail", + keyringBackend: keyring.BackendTest, + extraArgs: []string{"--unarmored-hex"}, + mustFail: true, + }, + { + name: "--unsafe --unarmored-hex fail with no user confirmation", + keyringBackend: keyring.BackendTest, + extraArgs: []string{"--unsafe", "--unarmored-hex"}, + userInput: "", + mustFail: true, + expectedOutput: "", + }, + { + name: "--unsafe --unarmored-hex succeed", + keyringBackend: keyring.BackendTest, + extraArgs: []string{"--unsafe", "--unarmored-hex"}, + userInput: "y\n", + mustFail: false, + expectedOutput: "2485e33678db4175dc0ecef2d6e1fc493d4a0d7f7ce83324b6ed70afe77f3485\n", + }, + { + name: "file keyring backend properly read password and user confirmation", + keyringBackend: keyring.BackendFile, + extraArgs: []string{"--unsafe", "--unarmored-hex"}, + // first 2 pass for creating the key, then unsafe export confirmation, then unlock keyring pass + userInput: "12345678\n12345678\ny\n12345678\n", + mustFail: false, + expectedOutput: "2485e33678db4175dc0ecef2d6e1fc493d4a0d7f7ce83324b6ed70afe77f3485\n", + }, } - mockIn.Reset("123456789\n123456789\n") - cmd.SetArgs(args) - - clientCtx := client.Context{}. - WithKeyringDir(kbHome). - WithKeyring(kb) - ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) - - require.NoError(t, cmd.ExecuteContext(ctx)) - - argsUnsafeOnly := append(args, "--unsafe") - cmd.SetArgs(argsUnsafeOnly) - require.Error(t, cmd.ExecuteContext(ctx)) - - argsUnarmoredHexOnly := append(args, "--unarmored-hex") - cmd.SetArgs(argsUnarmoredHexOnly) - require.Error(t, cmd.ExecuteContext(ctx)) - - argsUnsafeUnarmoredHex := append(args, "--unsafe", "--unarmored-hex") - cmd.SetArgs(argsUnsafeUnarmoredHex) - require.Error(t, cmd.ExecuteContext(ctx)) - - mockIn, mockOut := testutil.ApplyMockIO(cmd) - mockIn.Reset("y\n") - require.NoError(t, cmd.ExecuteContext(ctx)) - require.Equal(t, "2485e33678db4175dc0ecef2d6e1fc493d4a0d7f7ce83324b6ed70afe77f3485\n", mockOut.String()) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + kbHome := t.TempDir() + defaultArgs := []string{ + "keyname1", + fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome), + fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, tc.keyringBackend), + } + + cmd := ExportKeyCommand() + cmd.Flags().AddFlagSet(Commands("home").PersistentFlags()) + + cmd.SetArgs(append(defaultArgs, tc.extraArgs...)) + mockIn, mockOut := testutil.ApplyMockIO(cmd) + + mockIn.Reset(tc.userInput) + mockInBuf := bufio.NewReader(mockIn) + + // create a key + kb, err := keyring.New(sdk.KeyringServiceName(), tc.keyringBackend, kbHome, bufio.NewReader(mockInBuf)) + require.NoError(t, err) + t.Cleanup(func() { + kb.Delete("keyname1") // nolint:errcheck + }) + + path := sdk.GetConfig().GetFullFundraiserPath() + _, err = kb.NewAccount("keyname1", testutil.TestMnemonic, "", path, hd.Secp256k1) + require.NoError(t, err) + + clientCtx := client.Context{}. + WithKeyringDir(kbHome). + WithKeyring(kb). + WithInput(mockInBuf) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + err = cmd.ExecuteContext(ctx) + if tc.mustFail { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, mockOut.String()) + } + }) + } } diff --git a/client/keys/import.go b/client/keys/import.go index 2b7e230654ce..36662a8dd2e6 100644 --- a/client/keys/import.go +++ b/client/keys/import.go @@ -18,11 +18,11 @@ func ImportKeyCommand() *cobra.Command { Long: "Import a ASCII armored private key into the local keybase.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - buf := bufio.NewReader(cmd.InOrStdin()) clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } + buf := bufio.NewReader(clientCtx.Input) bz, err := ioutil.ReadFile(args[1]) if err != nil { diff --git a/client/keys/import_test.go b/client/keys/import_test.go index ea84408c2df5..ac05ed567daa 100644 --- a/client/keys/import_test.go +++ b/client/keys/import_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io/ioutil" + "os" "path/filepath" "testing" @@ -17,25 +18,50 @@ import ( ) func Test_runImportCmd(t *testing.T) { - cmd := ImportKeyCommand() - cmd.Flags().AddFlagSet(Commands("home").PersistentFlags()) - mockIn := testutil.ApplyMockIODiscardOutErr(cmd) + testCases := []struct { + name string + keyringBackend string + userInput string + expectError bool + }{ + { + name: "test backend success", + keyringBackend: keyring.BackendTest, + // key armor passphrase + userInput: "123456789\n", + }, + { + name: "test backend fail with wrong armor pass", + keyringBackend: keyring.BackendTest, + userInput: "987654321\n", + expectError: true, + }, + { + name: "file backend success", + keyringBackend: keyring.BackendFile, + // key armor passphrase + keyring password x2 + userInput: "123456789\n12345678\n12345678\n", + }, + { + name: "file backend fail with wrong armor pass", + keyringBackend: keyring.BackendFile, + userInput: "987654321\n12345678\n12345678\n", + expectError: true, + }, + { + name: "file backend fail with wrong keyring pass", + keyringBackend: keyring.BackendFile, + userInput: "123465789\n12345678\n87654321\n", + expectError: true, + }, + { + name: "file backend fail with no keyring pass", + keyringBackend: keyring.BackendFile, + userInput: "123465789\n", + expectError: true, + }, + } - // Now add a temporary keybase - kbHome := t.TempDir() - kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn) - - clientCtx := client.Context{}. - WithKeyringDir(kbHome). - WithKeyring(kb) - ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) - - require.NoError(t, err) - t.Cleanup(func() { - kb.Delete("keyname1") // nolint:errcheck - }) - - keyfile := filepath.Join(kbHome, "key.asc") armoredKey := `-----BEGIN TENDERMINT PRIVATE KEY----- salt: A790BB721D1C094260EA84F5E5B72289 kdf: bcrypt @@ -45,12 +71,48 @@ HbP+c6JmeJy9JXe2rbbF1QtCX1gLqGcDQPBXiCtFvP7/8wTZtVOPj8vREzhZ9ElO =f3l4 -----END TENDERMINT PRIVATE KEY----- ` - require.NoError(t, ioutil.WriteFile(keyfile, []byte(armoredKey), 0644)) - - mockIn.Reset("123456789\n") - cmd.SetArgs([]string{ - "keyname1", keyfile, - fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), - }) - require.NoError(t, cmd.ExecuteContext(ctx)) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cmd := ImportKeyCommand() + cmd.Flags().AddFlagSet(Commands("home").PersistentFlags()) + mockIn := testutil.ApplyMockIODiscardOutErr(cmd) + + // Now add a temporary keybase + kbHome := t.TempDir() + kb, err := keyring.New(sdk.KeyringServiceName(), tc.keyringBackend, kbHome, nil) + + clientCtx := client.Context{}. + WithKeyringDir(kbHome). + WithKeyring(kb). + WithInput(mockIn) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + require.NoError(t, err) + t.Cleanup(func() { + kb.Delete("keyname1") // nolint:errcheck + }) + + keyfile := filepath.Join(kbHome, "key.asc") + + require.NoError(t, ioutil.WriteFile(keyfile, []byte(armoredKey), 0644)) + + defer func() { + _ = os.RemoveAll(kbHome) + }() + + mockIn.Reset(tc.userInput) + cmd.SetArgs([]string{ + "keyname1", keyfile, + fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, tc.keyringBackend), + }) + + err = cmd.ExecuteContext(ctx) + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/client/query.go b/client/query.go index 85749a739a87..6c6f16b485e4 100644 --- a/client/query.go +++ b/client/query.go @@ -50,7 +50,9 @@ func (ctx Context) QueryStore(key tmbytes.HexBytes, storeName string) ([]byte, i } // QueryABCI performs a query to a Tendermint node with the provide RequestQuery. -// It returns the ResultQuery obtained from the query. +// It returns the ResultQuery obtained from the query. The height used to perform +// the query is the RequestQuery Height if it is non-zero, otherwise the context +// height is used. func (ctx Context) QueryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) { return ctx.queryABCI(req) } @@ -71,8 +73,16 @@ func (ctx Context) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) return abci.ResponseQuery{}, err } + var queryHeight int64 + if req.Height != 0 { + queryHeight = req.Height + } else { + // fallback on the context height + queryHeight = ctx.Height + } + opts := rpcclient.ABCIQueryOptions{ - Height: ctx.Height, + Height: queryHeight, Prove: req.Prove, } diff --git a/client/query_test.go b/client/query_test.go new file mode 100644 index 000000000000..a8e2725860ec --- /dev/null +++ b/client/query_test.go @@ -0,0 +1,62 @@ +// +build norace + +package client_test + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +func (s *IntegrationTestSuite) TestQueryABCIHeight() { + testCases := []struct { + name string + reqHeight int64 + ctxHeight int64 + expHeight int64 + }{ + { + name: "non zero request height", + reqHeight: 3, + ctxHeight: 1, // query at height 1 or 2 would cause an error + expHeight: 3, + }, + { + name: "empty request height - use context height", + reqHeight: 0, + ctxHeight: 3, + expHeight: 3, + }, + { + name: "empty request height and context height - use latest height", + reqHeight: 0, + ctxHeight: 0, + expHeight: 4, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.network.WaitForHeight(tc.expHeight) + + val := s.network.Validators[0] + + clientCtx := val.ClientCtx + clientCtx = clientCtx.WithHeight(tc.ctxHeight) + + req := abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", banktypes.StoreKey), + Height: tc.reqHeight, + Data: append(banktypes.BalancesPrefix, val.Address.Bytes()...), + Prove: true, + } + + res, err := clientCtx.QueryABCI(req) + s.Require().NoError(err) + + s.Require().Equal(tc.expHeight, res.Height) + }) + } +} diff --git a/client/rest/rest.go b/client/rest/rest.go index ac05891e04c7..1fd715a642e1 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -22,6 +22,7 @@ func addHTTPDeprecationHeaders(h http.Handler) http.Handler { }) } +// nolint // WithHTTPDeprecationHeaders returns a new *mux.Router, identical to its input // but with the addition of HTTP Deprecation headers. This is used to mark legacy // amino REST endpoints as deprecated in the REST API. diff --git a/client/rpc/block.go b/client/rpc/block.go index d6b79c9fe6da..530f7c45df73 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -15,7 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/rest" ) -//BlockCommand returns the verified block data for a given heights +// BlockCommand returns the verified block data for a given heights func BlockCommand() *cobra.Command { cmd := &cobra.Command{ Use: "block [height]", diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 66c594966ed7..7c68d1ab7c79 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -22,7 +22,7 @@ import ( // TODO these next two functions feel kinda hacky based on their placement -//ValidatorCommand returns the validator set for a given height +// ValidatorCommand returns the validator set for a given height func ValidatorCommand() *cobra.Command { cmd := &cobra.Command{ Use: "tendermint-validator-set [height]", diff --git a/codec/amino.go b/codec/amino.go index 78fd650ca4b8..72aed1caa350 100644 --- a/codec/amino.go +++ b/codec/amino.go @@ -13,7 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" ) -// deprecated: LegacyAmino defines a wrapper for an Amino codec that properly handles protobuf +// Deprecated: LegacyAmino defines a wrapper for an Amino codec that properly handles protobuf // types with Any's type LegacyAmino struct { Amino *amino.Codec diff --git a/contrib/images/simd-env/Dockerfile b/contrib/images/simd-env/Dockerfile index 1ccaeac657db..591592b7183e 100644 --- a/contrib/images/simd-env/Dockerfile +++ b/contrib/images/simd-env/Dockerfile @@ -8,7 +8,7 @@ ARG UID=1000 ARG GID=1000 USER ${UID}:${GID} -VOLUME [ /simd ] +VOLUME [ "/simd" ] WORKDIR /simd EXPOSE 26656 26657 ENTRYPOINT ["/usr/bin/wrapper.sh"] diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index febad555df9c..b18d6073228e 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -379,14 +379,17 @@ func (ks keystore) SignByAddress(address sdk.Address, msg []byte) ([]byte, types func (ks keystore) SaveLedgerKey(uid string, algo SignatureAlgo, hrp string, coinType, account, index uint32) (Info, error) { if !ks.options.SupportedAlgosLedger.Contains(algo) { - return nil, ErrUnsupportedSigningAlgo + return nil, fmt.Errorf( + "%w: signature algo %s is not defined in the keyring options", + ErrUnsupportedSigningAlgo, algo.Name(), + ) } hdPath := hd.NewFundraiserParams(account, coinType, index) priv, _, err := ledger.NewPrivKeySecp256k1(*hdPath, hrp) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to generate ledger key: %w", err) } return ks.writeLedgerKey(uid, priv.PubKey(), *hdPath, algo.Name()) diff --git a/crypto/keyring/keyring_ledger_test.go b/crypto/keyring/keyring_ledger_test.go index eb7e85f9e89c..b940970af1df 100644 --- a/crypto/keyring/keyring_ledger_test.go +++ b/crypto/keyring/keyring_ledger_test.go @@ -95,7 +95,8 @@ func TestAltKeyring_SaveLedgerKey(t *testing.T) { // Test unsupported Algo _, err = keyring.SaveLedgerKey("key", notSupportedAlgo{}, "cosmos", 118, 0, 0) - require.EqualError(t, err, ErrUnsupportedSigningAlgo.Error()) + require.Error(t, err) + require.Contains(t, err.Error(), ErrUnsupportedSigningAlgo.Error()) ledger, err := keyring.SaveLedgerKey("some_account", hd.Secp256k1, "cosmos", 118, 3, 1) if err != nil { @@ -103,6 +104,7 @@ func TestAltKeyring_SaveLedgerKey(t *testing.T) { t.Skip("ledger nano S: support for ledger devices is not available in this executable") return } + // The mock is available, check that the address is correct require.Equal(t, "some_account", ledger.GetName()) pubKey := ledger.GetPubKey() diff --git a/crypto/keyring/legacy.go b/crypto/keyring/legacy.go index 59bdc3fc5dad..f30513e03e0b 100644 --- a/crypto/keyring/legacy.go +++ b/crypto/keyring/legacy.go @@ -40,6 +40,7 @@ func NewLegacy(name, dir string, opts ...KeybaseOption) (LegacyKeybase, error) { var _ LegacyKeybase = dbKeybase{} +// nolint // dbKeybase combines encryption and storage implementation to provide a // full-featured key manager. // diff --git a/crypto/ledger/ledger_secp256k1.go b/crypto/ledger/ledger_secp256k1.go index 659181d30648..ee2f873544c4 100644 --- a/crypto/ledger/ledger_secp256k1.go +++ b/crypto/ledger/ledger_secp256k1.go @@ -73,13 +73,13 @@ func NewPrivKeySecp256k1Unsafe(path hd.BIP44Params) (types.LedgerPrivKey, error) func NewPrivKeySecp256k1(path hd.BIP44Params, hrp string) (types.LedgerPrivKey, string, error) { device, err := getDevice() if err != nil { - return nil, "", err + return nil, "", fmt.Errorf("failed to retrieve device: %w", err) } defer warnIfErrors(device.Close) pubKey, addr, err := getPubKeyAddrSafe(device, path, hrp) if err != nil { - return nil, "", err + return nil, "", fmt.Errorf("failed to recover pubkey: %w", err) } return PrivKeyLedgerSecp256k1{pubKey, path}, addr, nil @@ -261,7 +261,7 @@ func getPubKeyUnsafe(device SECP256K1, path hd.BIP44Params) (types.PubKey, error func getPubKeyAddrSafe(device SECP256K1, path hd.BIP44Params, hrp string) (types.PubKey, string, error) { publicKey, addr, err := device.GetAddressPubKeySECP256K1(path.DerivationPath(), hrp) if err != nil { - return nil, "", fmt.Errorf("address %s rejected", addr) + return nil, "", fmt.Errorf("%w: address rejected for path %s", err, path.String()) } // re-serialize in the 33-byte compressed format diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index a7e732c67224..e02f734a8e9c 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -46,6 +46,10 @@ module.exports = { "label": "v0.42", "key": "v0.42" }, + { + "label": "v0.44", + "key": "v0.44" + }, { "label": "master", "key": "master" diff --git a/docs/.vuepress/enhanceApp.js b/docs/.vuepress/enhanceApp.js new file mode 100644 index 000000000000..36cee6366fc8 --- /dev/null +++ b/docs/.vuepress/enhanceApp.js @@ -0,0 +1,8 @@ +export default ({ router }) => { + router.addRoutes([ + { path: '/master/spec/*', redirect: '/master/modules/' }, + { path: '/master/spec/governance/', redirect: '/master/modules/gov/' }, + { path: '/v0.41/', redirect: '/v0.42/' }, + { path: '/v0.43/', redirect: '/v0.44/' }, + ]) +} diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 98dbb33c324b..b919706e317a 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -6,7 +6,7 @@ If you want to open a PR on the Cosmos SDK to update the documentation, please f - Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...). - Always translate content living on `master`. -- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`. +- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/run-node/` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`. - Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation. ## Docs Build Workflow diff --git a/docs/README.md b/docs/README.md index 18398752a03f..a4323e5a6158 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,10 +19,10 @@ sections: desc: Discover how to build modules for the Cosmos SDK. icon: modules url: /building-modules/intro.html - - title: Interfaces - desc: Build interfaces for Cosmos SDK applications. + - title: Running a Node + desc: Running and interacting with nodes using the CLI and API. icon: interfaces - url: /interfaces/interfaces-intro.html + url: /run-node/ - title: Modules desc: Explore existing modules to build your application with. icon: specifications diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index e25c114edf53..88a8d8574474 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -223,9 +223,9 @@ These Legacy API endpoints are present in the SDK for backward compatibility pur ## Application Interface -[Interfaces](../interfaces/interfaces-intro.md) let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +[Interfaces](#command-line-grpc-services-and-rest-interfaces) let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application is the same as the daemon (e.g. `appd`), and defined in a file called `appd/main.go`. The file contains: +The main interface is the [Command-Line Interface](../core/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application is the same as the daemon (e.g. `appd`), and defined in a file called `appd/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appd` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appd`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appd query [query]` of the CLI. diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index daed33f823b2..78fcd202f0a6 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -14,7 +14,7 @@ This document describes the lifecycle of a transaction from creation to committe ### Transaction Creation -One of the main application interfaces is the command-line interface. The transaction `Tx` can be created by the user inputting a command in the following format from the [command-line](../interfaces/cli.md), providing the type of transaction in `[command]`, arguments in `[args]`, and configurations such as gas prices in `[flags]`: +One of the main application interfaces is the command-line interface. The transaction `Tx` can be created by the user inputting a command in the following format from the [command-line](../core/cli.md), providing the type of transaction in `[command]`, arguments in `[args]`, and configurations such as gas prices in `[flags]`: ```bash [appname] tx [command] [args] [flags] @@ -26,7 +26,7 @@ There are several required and optional flags for transaction creation. The `--f #### Gas and Fees -Additionally, there are several [flags](../interfaces/cli.md) users can use to indicate how much they are willing to pay in [fees](./gas-fees.md): +Additionally, there are several [flags](../core/cli.md) users can use to indicate how much they are willing to pay in [fees](./gas-fees.md): - `--gas` refers to how much [gas](./gas-fees.md), which represents computational resources, `Tx` consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing `auto` as the value for `--gas`. - `--gas-adjustment` (optional) can be used to scale `gas` up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. @@ -48,7 +48,7 @@ appd tx send 1000uatom --from --gas auto --ga #### Other Transaction Creation Methods -The command-line is an easy way to interact with an application, but `Tx` can also be created using a [REST interface](../interfaces/rest.md) or some other entrypoint defined by the application developer. From the user's perspective, the interaction depends on the web interface or wallet they are using (e.g. creating `Tx` using [Lunie.io](https://lunie.io/#/) and signing it with a Ledger Nano S). +The command-line is an easy way to interact with an application, but `Tx` can also be created using a [gRPC or REST interface](../core/grpc_rest.md) or some other entrypoint defined by the application developer. From the user's perspective, the interaction depends on the web interface or wallet they are using (e.g. creating `Tx` using [Lunie.io](https://lunie.io/#/) and signing it with a Ledger Nano S). ## Addition to Mempool diff --git a/docs/building-modules/errors.md b/docs/building-modules/errors.md index 3b6d90535e45..d55f57a21fa3 100644 --- a/docs/building-modules/errors.md +++ b/docs/building-modules/errors.md @@ -48,7 +48,3 @@ an error is of a particular kind via `Is`. If a module error is registered, the SDK `errors` package allows ABCI information to be extracted through the `ABCIInfo` API. The package also provides `ResponseCheckTx` and `ResponseDeliverTx` as auxiliary APIs to automatically get `CheckTx` and `DeliverTx` responses from an error. - -## Next {hide} - -Learn about [interfaces](../interfaces/interfaces-intro.md) {hide} diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 33afa51dbbb6..a890608c5baa 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -61,7 +61,7 @@ See an example implementation of a `message` from the `gov` module: ## Queries -A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `BaseApp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md). +A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `BaseApp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../basics/query-lifecycle.md). ### gRPC Queries diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 0f811db4bf75..856f401264a0 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -12,7 +12,7 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint adds commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../core/cli.md). This entrypoint adds commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 919ec1425c84..166ca4e36ae4 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -38,8 +38,8 @@ Let us go through the methods: - `RegisterInterfaces(codectypes.InterfaceRegistry)`: Registers a module's interface types and their concrete implementations as `proto.Message`. - `DefaultGenesis(codec.JSONMarshaler)`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. - `ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. -- `RegisterRESTRoutes(client.Context, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. -- `RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module. +- `RegisterRESTRoutes(client.Context, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [gRPC and REST](../core/grpc_rest.md) for more. +- `RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module. - `GetTxCmd()`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. - `GetQueryCmd()`: Return the root [`query` command](./module-interfaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. @@ -116,10 +116,10 @@ It implements the following methods: - `RegisterInterfaces(registry codectypes.InterfaceRegistry)`: Registers interface types and implementations of each of the application's `AppModuleBasic`. - `DefaultGenesis(cdc codec.JSONMarshaler)`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis(cdc codec.JSONMarshaler)`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application. - `ValidateGenesis(cdc codec.JSONMarshaler, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`](./genesis.md#validategenesis) function of each module. -- `RegisterRESTRoutes(ctx client.Context, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). +- `RegisterRESTRoutes(ctx client.Context, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../core/cli.md). - `RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC routes for modules. -- `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../interfaces/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). -- `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands to the application's [`rootQueryCommand`](../interfaces/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). +- `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../core/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../core/cli.md). +- `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands to the application's [`rootQueryCommand`](../core/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../core/cli.md). ### `Manager` diff --git a/docs/building-modules/query-services.md b/docs/building-modules/query-services.md index e9f7f8c77d59..973bee7a874d 100644 --- a/docs/building-modules/query-services.md +++ b/docs/building-modules/query-services.md @@ -66,7 +66,7 @@ func NewQuerier(keeper Keeper) sdk.Querier { } ``` -This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query. +This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../basics/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query. The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. diff --git a/docs/cn/README.md b/docs/cn/README.md index dd30ed000a04..2ef61ad9d2de 100644 --- a/docs/cn/README.md +++ b/docs/cn/README.md @@ -16,7 +16,7 @@ parent: - **[基础文档](./basics/)**:cosmos sdk 的基础概念文档,例如应用结构、交易的生命周期、账户管理等 - **[核心文档](./core/)**: cosmos sdk 的核心文档,例如`baseapp`,`store`,`server`等 - **[构建模块](./building-modules/)**: 对于模块开发者来说的一些重要概念,例如`message`,`keeper`,`handler`,`querier` -- **[接口](./interfaces/)**: 为 cosmos 应用设计接口的文档 +- **[接口](./run-node/)**: 为 cosmos 应用设计接口的文档 ## 开发资源 diff --git a/docs/cn/basics/accounts.md b/docs/cn/basics/accounts.md index c37e45aa69b7..e6d5cce4fa67 100644 --- a/docs/cn/basics/accounts.md +++ b/docs/cn/basics/accounts.md @@ -77,7 +77,7 @@ Cosmos SDK 使用一套称之为 [BIP32](https://github.com/bitcoin/bips/blob/ma +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/lazy_keybase.go -`lazyKeybase` 是 `dbKeybase` 的一个简单包装,它仅在要执行操作时锁定数据库,并在之后立即将其解锁。使用 `lazyKeybase`[命令行界面](../interfaces/cli.md) 可以在 [rest server](../interfaces/rest.md)运行时创建新的账户,它也可以同时传递多个 CLI 命令 +`lazyKeybase` 是 `dbKeybase` 的一个简单包装,它仅在要执行操作时锁定数据库,并在之后立即将其解锁。使用 `lazyKeybase`[命令行界面](../core/cli.md) 可以在 [rest server](../core/grpc_rest.md)运行时创建新的账户,它也可以同时传递多个 CLI 命令 ## 地址和公钥 diff --git a/docs/cn/basics/tx-lifecycle.md b/docs/cn/basics/tx-lifecycle.md index cae4644fa770..1845978752ee 100644 --- a/docs/cn/basics/tx-lifecycle.md +++ b/docs/cn/basics/tx-lifecycle.md @@ -6,7 +6,7 @@ ### Transaction 的创建 -命令行界面是主要的应用程序界面之一,`Tx` 可以由用户输入[以下命令](https://docs.cosmos.network/master/interfaces/cli.html)来创建,其中 `[command]` 是 `Tx` 的类型,`[args]` 是相关参数,`[flags]` 是相关配置例如 gas price: +命令行界面是主要的应用程序界面之一,`Tx` 可以由用户输入[以下命令](https://docs.cosmos.network/master/core/cli.html)来创建,其中 `[command]` 是 `Tx` 的类型,`[args]` 是相关参数,`[flags]` 是相关配置例如 gas price: ```bash [appname] tx [command] [args] [flags] @@ -18,7 +18,7 @@ #### Gas 和 Fee -此外,用户可以使用这几个[参数](https://docs.cosmos.network/master/interfaces/cli.html)来表明他们愿意支付多少 [fee](https://docs.cosmos.network/master/basics/gas-fees.html): +此外,用户可以使用这几个[参数](https://docs.cosmos.network/master/core/cli.html)来表明他们愿意支付多少 [fee](https://docs.cosmos.network/master/basics/gas-fees.html): - `--gas` 指的是 [gas](https://docs.cosmos.network/master/basics/gas-fees.html) 的数量,gas 代表 `Tx` 消耗的计算资源,需要消耗多少 gas 取决于具体的 `Tx`,在 `Tx` 执行之前无法被精确计算出来,但可以通过在 `--gas` 后带上参数 `auto` 来进行估算。 - `--gas-adjustment`(可选)可用于适当的增加 `gas`,以避免其被低估。例如,用户可以将 `gas-adjustment` 设为 1.5,那么被指定的 gas 将是被估算 gas 的 1.5 倍。 @@ -39,7 +39,7 @@ appcli tx send 1000uatom --from --gas auto -- #### 其他的 Transaction 创建方法 -命令行是与应用程序进行交互的一种简便方法,但是 `Tx` 也可以使用 [REST interface](https://docs.cosmos.network/master/interfaces/rest.html) 或应用程序开发人员定义的某些其他入口点来创建命令行。从用户的角度来看,交互方式取决于他们正在使用的是页面还是钱包(例如, `Tx` 使用 [Lunie.io](https://lunie.io/#/) 创建并使用 Ledger Nano S 对其进行签名)。 +命令行是与应用程序进行交互的一种简便方法,但是 `Tx` 也可以使用 [REST interface](https://docs.cosmos.network/master/core/grpc_rest.html) 或应用程序开发人员定义的某些其他入口点来创建命令行。从用户的角度来看,交互方式取决于他们正在使用的是页面还是钱包(例如, `Tx` 使用 [Lunie.io](https://lunie.io/#/) 创建并使用 Ledger Nano S 对其进行签名)。 ## 添加到交易池 diff --git a/docs/cn/clients/service-providers.md b/docs/cn/clients/service-providers.md index 7350b98d8110..37ddf4893dd8 100644 --- a/docs/cn/clients/service-providers.md +++ b/docs/cn/clients/service-providers.md @@ -2,7 +2,7 @@ 我们将“服务提供商”定义为可以为最终用户提供服务的实体,这些实体涉及与基于 Cosmos-SDK 的区块链(包括 Cosmos Hub)的某种形式的交互。更具体地说,本文档将集中于与 token 的交互。 -本节不涉及想要提供[轻客户端](https://github.com/cosmos/cosmos-sdk/tree/master/docs/interfaces/lite)功能的钱包开发者。服务提供商将作为最终用户的区块链的可信接入点。 +本节不涉及想要提供[轻客户端](https://docs.tendermint.com/master/tendermint-core/light-client.html)功能的钱包开发者。服务提供商将作为最终用户的区块链的可信接入点。 ## 架构的高级描述 diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index b9052daf4659..fa4a816e1cc8 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -2269,6 +2269,7 @@ VersionInfo is the type for the GetNodeInfoResponse message. | `build_tags` | [string](#string) | | | | `go_version` | [string](#string) | | | | `build_deps` | [Module](#cosmos.base.tendermint.v1beta1.Module) | repeated | | +| `cosmos_sdk_version` | [string](#string) | | | @@ -6527,6 +6528,7 @@ RPC method. | ----- | ---- | ----- | ----------- | | `events` | [string](#string) | repeated | events is the list of transaction event type. | | `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an pagination for the request. | +| `order_by` | [OrderBy](#cosmos.tx.v1beta1.OrderBy) | | | @@ -6599,6 +6601,19 @@ BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC metho | BROADCAST_MODE_ASYNC | 3 | BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns immediately. | + + + +### OrderBy +OrderBy defines the sorting order + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ORDER_BY_UNSPECIFIED | 0 | ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. | +| ORDER_BY_ASC | 1 | ORDER_BY_ASC defines ascending order | +| ORDER_BY_DESC | 2 | ORDER_BY_DESC defines descending order | + + @@ -9491,11 +9506,6 @@ GenesisState defines the ibc module's genesis state. -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `events` | [string](#string) | repeated | events is the list of transaction event type. | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an pagination for the request. | -| `order_by` | [OrderBy](#cosmos.tx.v1beta1.OrderBy) | | | @@ -9571,20 +9581,6 @@ state and if the client is frozen. - - -### OrderBy -OrderBy defines the sorting order - -| Name | Number | Description | -| ---- | ------ | ----------- | -| ORDER_BY_UNSPECIFIED | 0 | ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. | -| ORDER_BY_ASC | 1 | ORDER_BY_ASC defines ascending order | -| ORDER_BY_DESC | 2 | ORDER_BY_DESC defines descending order | - - - - diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 529fd0d17ab8..b07bf451a66d 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -125,7 +125,7 @@ Once the transaction bytes are generated, there are currently three ways of broa #### CLI -Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line. +Application developers create entrypoints to the application by creating a [command-line interface](../core/cli.md), [gRPC and/or REST interface](../core/grpc_rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line. For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. CLI commands actually bundle all the steps of transaction processing into one simple command: creating messages, generating transactions and broadcasting. For concrete examples, see the [Interacting with a Node](../run-node/interact-node.md) section. An example transaction made using CLI looks like: diff --git a/docs/kr/clients/service-providers.md b/docs/kr/clients/service-providers.md index 2c9b5aaea2c9..c99aa3d2e462 100755 --- a/docs/kr/clients/service-providers.md +++ b/docs/kr/clients/service-providers.md @@ -2,7 +2,7 @@ '서비스 제공자'는 코스모스 SDK 기반 블록체인(코스모스 허브도 포함됩니다)과 교류하는 서비스를 엔드유저에게 제공하는 특정 인원/기관을 뜻합니다. 이 문서는 주로 토큰 인터랙션에 대한 정보를 다룹니다. -다음 항목은 [Light-Client](https://github.com/cosmos/cosmos-sdk/tree/master/docs/interfaces/lite) 기능을 제공하려는 월렛 개발자들에게 해당하지 않습니다. 서비스 제공자는 엔드 유저와 블록체인을 이어주는 신뢰할 수 있는 기관/개인입니다. +다음 항목은 [Light-Client](https://docs.tendermint.com/master/tendermint-core/light-client.html) 기능을 제공하려는 월렛 개발자들에게 해당하지 않습니다. 서비스 제공자는 엔드 유저와 블록체인을 이어주는 신뢰할 수 있는 기관/개인입니다. ## 보편적 아키텍처 설명 diff --git a/docs/versions b/docs/versions index d5dc85eb286f..aec06db250e3 100644 --- a/docs/versions +++ b/docs/versions @@ -1,2 +1,4 @@ master master launchpad/backports v0.39 +release/v0.42.x v0.42 +release/v0.44.x v0.44 diff --git a/go.mod b/go.mod index 17ada7cff107..dcae062fd368 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/btcsuite/btcutil v1.0.2 github.com/confio/ics23/go v0.6.6 github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/iavl v0.16.0 + github.com/cosmos/iavl v0.17.1 github.com/cosmos/ledger-cosmos-go v0.11.1 github.com/dgraph-io/ristretto v0.0.3 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect @@ -48,12 +48,11 @@ require ( github.com/tendermint/btcd v0.1.1 github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 github.com/tendermint/go-amino v0.16.0 - github.com/tendermint/tendermint v0.34.10 + github.com/tendermint/tendermint v0.34.13 github.com/tendermint/tm-db v0.6.4 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f - google.golang.org/grpc v1.37.0 + google.golang.org/grpc v1.40.0 google.golang.org/protobuf v1.26.0 gopkg.in/ini.v1 v1.61.0 // indirect gopkg.in/yaml.v2 v2.4.0 @@ -62,3 +61,5 @@ require ( replace google.golang.org/grpc => google.golang.org/grpc v1.33.2 replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + +replace github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 diff --git a/go.sum b/go.sum index 5e35bfa2be54..b48ef0649559 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= @@ -10,8 +11,9 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= -github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= @@ -21,6 +23,11 @@ github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -29,6 +36,8 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/adlio/schema v1.1.13 h1:LeNMVg5Z1FX+Qgz8tJUijBLRdcpbFUElz+d1489On98= +github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -55,6 +64,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -73,12 +83,15 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -89,6 +102,10 @@ github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45Nqnlp github.com/confio/ics23/go v0.6.3/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/confio/ics23/go v0.6.6 h1:pkOy18YxxJ/r0XFDCnrl4Bjv6h4LkBSpLS6F38mrKL8= github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -97,6 +114,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -105,8 +123,10 @@ github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4x github.com/cosmos/iavl v0.15.0-rc3.0.20201009144442-230e9bdf52cd/go.mod h1:3xOIaNNX19p0QrX0VqWa6voPRoJRGGYtny+DH8NEPvE= github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7uMjgxke/I= github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4= -github.com/cosmos/iavl v0.16.0 h1:ICIOB8xysirTX27GmVAaoeSpeozzgSu9d49w36xkVJA= -github.com/cosmos/iavl v0.16.0/go.mod h1:2A8O/Jz9YwtjqXMO0CjnnbTYEEaovE8jWcwrakH3PoE= +github.com/cosmos/iavl v0.17.1 h1:b/Cl8h1PRMvsu24+TYNlKchIu7W6tmxIBGe6E9u2Ybw= +github.com/cosmos/iavl v0.17.1/go.mod h1:7aisPZK8yCpQdy3PMvKeO+bhq1NwDjUwjzxwwROUxFk= +github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 h1:DdzS1m6o/pCqeZ8VOAit/gyATedRgjvkVI+UCrLpyuU= +github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= @@ -115,6 +135,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -133,6 +154,10 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -159,6 +184,7 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -178,6 +204,7 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -247,6 +274,7 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -331,9 +359,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -357,7 +388,6 @@ github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -366,10 +396,12 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -400,6 +432,16 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -408,6 +450,8 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -500,10 +544,15 @@ github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZ github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -553,6 +602,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= @@ -566,8 +616,8 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= -github.com/tendermint/tendermint v0.34.10 h1:wBOc/It8sh/pVH9np2V5fBvRmIyFN/bUrGPx+eAHexs= -github.com/tendermint/tendermint v0.34.10/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0= +github.com/tendermint/tendermint v0.34.13 h1:fu+tsHudbOr5PvepjH0q47Jae59hQAvn3IqAHv2EbC8= +github.com/tendermint/tendermint v0.34.13/go.mod h1:6RVVRBqwtKhA+H59APKumO+B7Nye4QXSFc6+TYxAxCI= github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8= github.com/tendermint/tm-db v0.6.4 h1:3N2jlnYQkXNQclQwd/eKV/NzlqPlfK21cpRRIx80XXQ= @@ -579,6 +629,8 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -665,6 +717,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -673,8 +726,10 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -703,15 +758,18 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -724,20 +782,27 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -846,6 +911,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/proto/cosmos/base/tendermint/v1beta1/query.proto b/proto/cosmos/base/tendermint/v1beta1/query.proto index 50cb5852cdf2..505d4131d90d 100644 --- a/proto/cosmos/base/tendermint/v1beta1/query.proto +++ b/proto/cosmos/base/tendermint/v1beta1/query.proto @@ -116,13 +116,14 @@ message GetNodeInfoResponse { // VersionInfo is the type for the GetNodeInfoResponse message. message VersionInfo { - string name = 1; - string app_name = 2; - string version = 3; - string git_commit = 4; - string build_tags = 5; - string go_version = 6; - repeated Module build_deps = 7; + string name = 1; + string app_name = 2; + string version = 3; + string git_commit = 4; + string build_tags = 5; + string go_version = 6; + repeated Module build_deps = 7; + string cosmos_sdk_version = 8; } // Module is the type for VersionInfo diff --git a/simapp/ante_handler.go b/simapp/ante_handler.go new file mode 100644 index 000000000000..954a3b7c55b6 --- /dev/null +++ b/simapp/ante_handler.go @@ -0,0 +1,36 @@ +package simapp + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/gov/types" + channelkeeper "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/keeper" + ibcante "github.com/cosmos/cosmos-sdk/x/ibc/core/ante" +) + +func NewAnteHandler( + ak ante.AccountKeeper, + bankKeeper types.BankKeeper, //nolint:interfacer + sigGasConsumer ante.SignatureVerificationGasConsumer, + signModeHandler signing.SignModeHandler, + channelKeeper channelkeeper.Keeper, +) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ante.NewRejectExtensionOptionsDecorator(), + ante.NewMempoolFeeDecorator(), + ante.NewValidateBasicDecorator(), + ante.TxTimeoutHeightDecorator{}, + ante.NewValidateMemoDecorator(ak), + ante.NewConsumeGasForTxSizeDecorator(ak), + ante.NewRejectFeeGranterDecorator(), + ante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators + ante.NewValidateSigCountDecorator(ak), + ante.NewDeductFeeDecorator(ak, bankKeeper), + ante.NewSigGasConsumeDecorator(ak, sigGasConsumer), + ante.NewSigVerificationDecorator(ak, signModeHandler), + ante.NewIncrementSequenceDecorator(ak), + ibcante.NewAnteDecorator(channelKeeper), + ) +} diff --git a/simapp/app.go b/simapp/app.go index 5eebfebb0f48..b60693f7a949 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -215,7 +215,7 @@ func NewSimApp( evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testing") app := &SimApp{ BaseApp: bApp, @@ -350,7 +350,7 @@ func NewSimApp( // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 app.mm.SetOrderBeginBlockers( - upgradetypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, + upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, ) app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName) @@ -403,9 +403,9 @@ func NewSimApp( app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) app.SetAnteHandler( - ante.NewAnteHandler( + NewAnteHandler( app.AccountKeeper, app.BankKeeper, ante.DefaultSigVerificationGasConsumer, - encodingConfig.TxConfig.SignModeHandler(), + encodingConfig.TxConfig.SignModeHandler(), app.IBCKeeper.ChannelKeeper, ), ) app.SetEndBlocker(app.EndBlocker) diff --git a/simapp/simd/cmd/genaccounts.go b/simapp/simd/cmd/genaccounts.go index 57de144c36b4..7bf3d370f7bf 100644 --- a/simapp/simd/cmd/genaccounts.go +++ b/simapp/simd/cmd/genaccounts.go @@ -48,22 +48,25 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa config.SetRoot(clientCtx.HomeDir) + var kr keyring.Keyring addr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { inBuf := bufio.NewReader(cmd.InOrStdin()) keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) - - // attempt to lookup address from Keybase if no address was provided - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf) - if err != nil { - return err + if keyringBackend != "" && clientCtx.Keyring == nil { + var err error + kr, err = keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf) + if err != nil { + return err + } + } else { + kr = clientCtx.Keyring } - info, err := kb.Key(args[0]) + info, err := kr.Key(args[0]) if err != nil { - return fmt.Errorf("failed to get address from Keybase: %w", err) + return fmt.Errorf("failed to get address from Keyring: %w", err) } - addr = info.GetAddress() } @@ -148,7 +151,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa appState[authtypes.ModuleName] = authGenStateBz - bankGenState := banktypes.GetGenesisStateFromAppState(depCdc, appState) + bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState) bankGenState.Balances = append(bankGenState.Balances, balances) bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...) diff --git a/simapp/simd/cmd/genaccounts_test.go b/simapp/simd/cmd/genaccounts_test.go index 9efc5343e7a3..813bf4b88e92 100644 --- a/simapp/simd/cmd/genaccounts_test.go +++ b/simapp/simd/cmd/genaccounts_test.go @@ -3,6 +3,9 @@ package cmd_test import ( "context" "fmt" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" "testing" "github.com/spf13/viper" @@ -25,28 +28,39 @@ var testMbm = module.NewBasicManager(genutil.AppModuleBasic{}) func TestAddGenesisAccountCmd(t *testing.T) { _, _, addr1 := testdata.KeyTestPubAddr() tests := []struct { - name string - addr string - denom string - expectErr bool + name string + addr string + denom string + withKeyring bool + expectErr bool }{ { - name: "invalid address", - addr: "", - denom: "1000atom", - expectErr: true, + name: "invalid address", + addr: "", + denom: "1000atom", + withKeyring: false, + expectErr: true, }, { - name: "valid address", - addr: addr1.String(), - denom: "1000atom", - expectErr: false, + name: "valid address", + addr: addr1.String(), + denom: "1000atom", + withKeyring: false, + expectErr: false, }, { - name: "multiple denoms", - addr: addr1.String(), - denom: "1000atom, 2000stake", - expectErr: false, + name: "multiple denoms", + addr: addr1.String(), + denom: "1000atom, 2000stake", + withKeyring: false, + expectErr: false, + }, + { + name: "with keyring", + addr: "ser", + denom: "1000atom", + withKeyring: true, + expectErr: false, }, } @@ -65,6 +79,15 @@ func TestAddGenesisAccountCmd(t *testing.T) { serverCtx := server.NewContext(viper.New(), cfg, logger) clientCtx := client.Context{}.WithJSONMarshaler(appCodec).WithHomeDir(home) + if tc.withKeyring { + path := hd.CreateHDPath(118, 0, 0).String() + kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil) + require.NoError(t, err) + _, _, err = kr.NewMnemonic(tc.addr, keyring.English, path, hd.Secp256k1) + require.NoError(t, err) + clientCtx = clientCtx.WithKeyring(kr) + } + ctx := context.Background() ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index b9027938be26..5b1cd1ca5eb7 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -46,7 +46,6 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { WithLegacyAmino(encodingConfig.Amino). WithInput(os.Stdin). WithAccountRetriever(types.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). WithHomeDir(simapp.DefaultNodeHome). WithViper("") // In simapp, we don't use any prefix for env variables. @@ -76,6 +75,8 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { authclient.Codec = encodingConfig.Marshaler + cfg := sdk.GetConfig() + cfg.Seal() rootCmd.AddCommand( genutilcli.InitCmd(simapp.ModuleBasics, simapp.DefaultNodeHome), diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 0717b398427c..f55873adab12 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -289,7 +289,10 @@ func initGenFiles( var bankGenState banktypes.GenesisState clientCtx.JSONMarshaler.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) - bankGenState.Balances = genBalances + bankGenState.Balances = banktypes.SanitizeGenesisBalances(genBalances) + for _, bal := range bankGenState.Balances { + bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...) + } appGenState[banktypes.ModuleName] = clientCtx.JSONMarshaler.MustMarshalJSON(&bankGenState) appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") diff --git a/simapp/simd/cmd/testnet_test.go b/simapp/simd/cmd/testnet_test.go new file mode 100644 index 000000000000..6b74d821273a --- /dev/null +++ b/simapp/simd/cmd/testnet_test.go @@ -0,0 +1,50 @@ +package cmd + +import ( + "context" + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/simapp" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" +) + +func Test_TestnetCmd(t *testing.T) { + home := t.TempDir() + encodingConfig := simapp.MakeTestEncodingConfig() + logger := log.NewNopLogger() + cfg, err := genutiltest.CreateDefaultTendermintConfig(home) + require.NoError(t, err) + + err = genutiltest.ExecInitCmd(simapp.ModuleBasics, home, encodingConfig.Marshaler) + require.NoError(t, err) + + serverCtx := server.NewContext(viper.New(), cfg, logger) + clientCtx := client.Context{}. + WithJSONMarshaler(encodingConfig.Marshaler). + WithHomeDir(home). + WithTxConfig(encodingConfig.TxConfig) + + ctx := context.Background() + ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) + ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) + cmd := testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}) + cmd.SetArgs([]string{fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), fmt.Sprintf("--output-dir=%s", home)}) + err = cmd.ExecuteContext(ctx) + require.NoError(t, err) + + genFile := cfg.GenesisFile() + appState, _, err := genutiltypes.GenesisStateFromGenFile(genFile) + require.NoError(t, err) + + bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Marshaler, appState) + require.NotEmpty(t, bankGenState.Supply.String()) +} diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 83f2ea45351f..6921b4875a6f 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -213,9 +213,9 @@ func createIncrementalAccounts(accNum int) []sdk.AccAddress { // start at 100 so we can make up to 999 test addresses with valid test addresses for i := 100; i < (accNum + 100); i++ { numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string - buffer.WriteString(numString) //adding on final two digits to make addresses unique + buffer.WriteString(numString) // adding on final two digits to make addresses unique res, _ := sdk.AccAddressFromHex(buffer.String()) bech := res.String() addr, _ := TestAddr(buffer.String(), bech) diff --git a/store/cachekv/memiterator.go b/store/cachekv/memiterator.go index b197ac141660..0a4bc57a6406 100644 --- a/store/cachekv/memiterator.go +++ b/store/cachekv/memiterator.go @@ -1,107 +1,50 @@ package cachekv import ( - "errors" - dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/cosmos/cosmos-sdk/store/types" ) // Iterates over iterKVCache items. // if key is nil, means it was deleted. // Implements Iterator. type memIterator struct { - start, end []byte - items []*kv.Pair - ascending bool -} - -func newMemIterator(start, end []byte, items *kv.List, ascending bool) *memIterator { - itemsInDomain := make([]*kv.Pair, 0, items.Len()) - - var entered bool - - for e := items.Front(); e != nil; e = e.Next() { - item := e.Value - if !dbm.IsKeyInDomain(item.Key, start, end) { - if entered { - break - } - - continue - } - - itemsInDomain = append(itemsInDomain, item) - entered = true - } + types.Iterator - return &memIterator{ - start: start, - end: end, - items: itemsInDomain, - ascending: ascending, - } + deleted map[string]struct{} } -func (mi *memIterator) Domain() ([]byte, []byte) { - return mi.start, mi.end -} +func newMemIterator(start, end []byte, items *dbm.MemDB, deleted map[string]struct{}, ascending bool) *memIterator { + var iter types.Iterator + var err error -func (mi *memIterator) Valid() bool { - return len(mi.items) > 0 -} + if ascending { + iter, err = items.Iterator(start, end) + } else { + iter, err = items.ReverseIterator(start, end) + } -func (mi *memIterator) assertValid() { - if err := mi.Error(); err != nil { + if err != nil { panic(err) } -} -func (mi *memIterator) Next() { - mi.assertValid() - - if mi.ascending { - mi.items = mi.items[1:] - } else { - mi.items = mi.items[:len(mi.items)-1] + newDeleted := make(map[string]struct{}) + for k, v := range deleted { + newDeleted[k] = v } -} -func (mi *memIterator) Key() []byte { - mi.assertValid() + return &memIterator{ + Iterator: iter, - if mi.ascending { - return mi.items[0].Key + deleted: newDeleted, } - - return mi.items[len(mi.items)-1].Key } func (mi *memIterator) Value() []byte { - mi.assertValid() - - if mi.ascending { - return mi.items[0].Value - } - - return mi.items[len(mi.items)-1].Value -} - -func (mi *memIterator) Close() error { - mi.start = nil - mi.end = nil - mi.items = nil - - return nil -} - -// Error returns an error if the memIterator is invalid defined by the Valid -// method. -func (mi *memIterator) Error() error { - if !mi.Valid() { - return errors.New("invalid memIterator") + key := mi.Iterator.Key() + if _, ok := mi.deleted[string(key)]; ok { + return nil } - - return nil + return mi.Iterator.Value() } diff --git a/store/cachekv/store.go b/store/cachekv/store.go index cd7087c5dc7b..2544e18c2ae9 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -20,17 +20,17 @@ import ( // If value is nil but deleted is false, it means the parent doesn't have the // key. (No need to delete upon Write()) type cValue struct { - value []byte - deleted bool - dirty bool + value []byte + dirty bool } // Store wraps an in-memory cache around an underlying types.KVStore. type Store struct { mtx sync.Mutex cache map[string]*cValue + deleted map[string]struct{} unsortedCache map[string]struct{} - sortedCache *kv.List // always ascending sorted + sortedCache *dbm.MemDB // always ascending sorted parent types.KVStore } @@ -40,8 +40,9 @@ var _ types.CacheKVStore = (*Store)(nil) func NewStore(parent types.KVStore) *Store { return &Store{ cache: make(map[string]*cValue), + deleted: make(map[string]struct{}), unsortedCache: make(map[string]struct{}), - sortedCache: kv.NewList(), + sortedCache: dbm.NewMemDB(), parent: parent, } } @@ -55,7 +56,6 @@ func (store *Store) GetStoreType() types.StoreType { func (store *Store) Get(key []byte) (value []byte) { store.mtx.Lock() defer store.mtx.Unlock() - defer telemetry.MeasureSince(time.Now(), "store", "cachekv", "get") types.AssertValidKey(key) @@ -74,7 +74,6 @@ func (store *Store) Get(key []byte) (value []byte) { func (store *Store) Set(key []byte, value []byte) { store.mtx.Lock() defer store.mtx.Unlock() - defer telemetry.MeasureSince(time.Now(), "store", "cachekv", "set") types.AssertValidKey(key) types.AssertValidValue(value) @@ -122,7 +121,7 @@ func (store *Store) Write() { cacheValue := store.cache[key] switch { - case cacheValue.deleted: + case store.isDeleted(key): store.parent.Delete([]byte(key)) case cacheValue.value == nil: // Skip, it already doesn't exist in parent. @@ -133,8 +132,9 @@ func (store *Store) Write() { // Clear the cache store.cache = make(map[string]*cValue) + store.deleted = make(map[string]struct{}) store.unsortedCache = make(map[string]struct{}) - store.sortedCache = kv.NewList() + store.sortedCache = dbm.NewMemDB() } // CacheWrap implements CacheWrapper. @@ -173,7 +173,7 @@ func (store *Store) iterator(start, end []byte, ascending bool) types.Iterator { } store.dirtyItems(start, end) - cache = newMemIterator(start, end, store.sortedCache, ascending) + cache = newMemIterator(start, end, store.sortedCache, store.deleted, ascending) return newCacheMergeIterator(parent, cache, ascending) } @@ -182,7 +182,7 @@ func (store *Store) iterator(start, end []byte, ascending bool) types.Iterator { // from string -> []byte to speed up operations, it is not meant // to be used generally, but for a specific pattern to check for available // keys within a domain. -func strToByte(s string) []byte { +func strToBytes(s string) []byte { var b []byte hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b)) hdr.Cap = len(s) @@ -202,16 +202,33 @@ func byteSliceToStr(b []byte) string { // Constructs a slice of dirty items, to use w/ memIterator. func (store *Store) dirtyItems(start, end []byte) { - unsorted := make([]*kv.Pair, 0) - n := len(store.unsortedCache) - for key := range store.unsortedCache { - if dbm.IsKeyInDomain(strToByte(key), start, end) { + unsorted := make([]*kv.Pair, 0) + // If the unsortedCache is too big, its costs too much to determine + // whats in the subset we are concerned about. + // If you are interleaving iterator calls with writes, this can easily become an + // O(N^2) overhead. + // Even without that, too many range checks eventually becomes more expensive + // than just not having the cache. + if n >= 1024 { + for key := range store.unsortedCache { cacheValue := store.cache[key] unsorted = append(unsorted, &kv.Pair{Key: []byte(key), Value: cacheValue.value}) } + } else { + // else do a linear scan to determine if the unsorted pairs are in the pool. + for key := range store.unsortedCache { + if dbm.IsKeyInDomain(strToBytes(key), start, end) { + cacheValue := store.cache[key] + unsorted = append(unsorted, &kv.Pair{Key: []byte(key), Value: cacheValue.value}) + } + } } + store.clearUnsortedCacheSubset(unsorted) +} +func (store *Store) clearUnsortedCacheSubset(unsorted []*kv.Pair) { + n := len(store.unsortedCache) if len(unsorted) == n { // This pattern allows the Go compiler to emit the map clearing idiom for the entire map. for key := range store.unsortedCache { delete(store.unsortedCache, key) @@ -221,32 +238,21 @@ func (store *Store) dirtyItems(start, end []byte) { delete(store.unsortedCache, byteSliceToStr(kv.Key)) } } - sort.Slice(unsorted, func(i, j int) bool { return bytes.Compare(unsorted[i].Key, unsorted[j].Key) < 0 }) - for e := store.sortedCache.Front(); e != nil && len(unsorted) != 0; { - uitem := unsorted[0] - sitem := e.Value - comp := bytes.Compare(uitem.Key, sitem.Key) - - switch comp { - case -1: - unsorted = unsorted[1:] - - store.sortedCache.InsertBefore(uitem, e) - case 1: - e = e.Next() - case 0: - unsorted = unsorted[1:] - e.Value = uitem - e = e.Next() + for _, item := range unsorted { + if item.Value == nil { + // deleted element, tracked by store.deleted + // setting arbitrary value + store.sortedCache.Set(item.Key, []byte{}) + continue + } + err := store.sortedCache.Set(item.Key, item.Value) + if err != nil { + panic(err) } - } - - for _, kvp := range unsorted { - store.sortedCache.PushBack(kvp) } } @@ -255,12 +261,22 @@ func (store *Store) dirtyItems(start, end []byte) { // Only entrypoint to mutate store.cache. func (store *Store) setCacheValue(key, value []byte, deleted bool, dirty bool) { - store.cache[string(key)] = &cValue{ - value: value, - deleted: deleted, - dirty: dirty, + keyStr := byteSliceToStr(key) + store.cache[keyStr] = &cValue{ + value: value, + dirty: dirty, + } + if deleted { + store.deleted[keyStr] = struct{}{} + } else { + delete(store.deleted, keyStr) } if dirty { store.unsortedCache[string(key)] = struct{}{} } } + +func (store *Store) isDeleted(key string) bool { + _, ok := store.deleted[key] + return ok +} diff --git a/store/gaskv/store.go b/store/gaskv/store.go index d5c1f86c20aa..812d08972011 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -19,7 +19,6 @@ type Store struct { } // NewStore returns a reference to a new GasKVStore. -// nolint func NewStore(parent types.KVStore, gasMeter types.GasMeter, gasConfig types.GasConfig) *Store { kvs := &Store{ gasMeter: gasMeter, @@ -36,8 +35,6 @@ func (gs *Store) GetStoreType() types.StoreType { // Implements KVStore. func (gs *Store) Get(key []byte) (value []byte) { - defer telemetry.MeasureSince(time.Now(), "store", "gaskv", "get") - gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostFlat, types.GasReadCostFlatDesc) value = gs.parent.Get(key) @@ -49,8 +46,6 @@ func (gs *Store) Get(key []byte) (value []byte) { // Implements KVStore. func (gs *Store) Set(key []byte, value []byte) { - defer telemetry.MeasureSince(time.Now(), "store", "gaskv", "set") - types.AssertValidKey(key) types.AssertValidValue(value) gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostFlat, types.GasWriteCostFlatDesc) diff --git a/store/types/gas.go b/store/types/gas.go index c6c94f859e02..730b03941c29 100644 --- a/store/types/gas.go +++ b/store/types/gas.go @@ -20,6 +20,12 @@ const ( // Gas measured by the SDK type Gas = uint64 +// ErrorNegativeGasConsumed defines an error thrown when the amount of gas refunded results in a +// negative gas consumed amount. +type ErrorNegativeGasConsumed struct { + Descriptor string +} + // ErrorOutOfGas defines an error thrown when an action results in out of gas. type ErrorOutOfGas struct { Descriptor string @@ -37,6 +43,7 @@ type GasMeter interface { GasConsumedToLimit() Gas Limit() Gas ConsumeGas(amount Gas, descriptor string) + RefundGas(amount Gas, descriptor string) IsPastLimit() bool IsOutOfGas() bool String() string @@ -91,7 +98,20 @@ func (g *basicGasMeter) ConsumeGas(amount Gas, descriptor string) { if g.consumed > g.limit { panic(ErrorOutOfGas{descriptor}) } +} + +// RefundGas will deduct the given amount from the gas consumed. If the amount is greater than the +// gas consumed, the function will panic. +// +// Use case: This functionality enables refunding gas to the transaction or block gas pools so that +// EVM-compatible chains can fully support the go-ethereum StateDb interface. +// See https://github.com/cosmos/cosmos-sdk/pull/9403 for reference. +func (g *basicGasMeter) RefundGas(amount Gas, descriptor string) { + if g.consumed < amount { + panic(ErrorNegativeGasConsumed{Descriptor: descriptor}) + } + g.consumed -= amount } func (g *basicGasMeter) IsPastLimit() bool { @@ -138,6 +158,20 @@ func (g *infiniteGasMeter) ConsumeGas(amount Gas, descriptor string) { } } +// RefundGas will deduct the given amount from the gas consumed. If the amount is greater than the +// gas consumed, the function will panic. +// +// Use case: This functionality enables refunding gas to the trasaction or block gas pools so that +// EVM-compatible chains can fully support the go-ethereum StateDb interface. +// See https://github.com/cosmos/cosmos-sdk/pull/9403 for reference. +func (g *infiniteGasMeter) RefundGas(amount Gas, descriptor string) { + if g.consumed < amount { + panic(ErrorNegativeGasConsumed{Descriptor: descriptor}) + } + + g.consumed -= amount +} + func (g *infiniteGasMeter) IsPastLimit() bool { return false } diff --git a/store/types/gas_test.go b/store/types/gas_test.go index bd62d463cd67..51dfe363cb3c 100644 --- a/store/types/gas_test.go +++ b/store/types/gas_test.go @@ -16,10 +16,13 @@ func TestInfiniteGasMeter(t *testing.T) { meter.ConsumeGas(10, "consume 10") require.Equal(t, uint64(10), meter.GasConsumed()) require.Equal(t, uint64(10), meter.GasConsumedToLimit()) + meter.RefundGas(1, "refund 1") + require.Equal(t, uint64(9), meter.GasConsumed()) require.False(t, meter.IsPastLimit()) require.False(t, meter.IsOutOfGas()) meter.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64") require.Panics(t, func() { meter.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") }) + require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") }) } func TestGasMeter(t *testing.T) { @@ -57,6 +60,11 @@ func TestGasMeter(t *testing.T) { require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum) require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit") require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1") + + require.NotPanics(t, func() { meter.RefundGas(1, "refund 1") }) + require.Equal(t, meter.GasConsumed(), meter.Limit(), "Gas consumption not match limit+1") + require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") }) + meter2 := NewGasMeter(math.MaxUint64) meter2.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64") require.Panics(t, func() { meter2.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") }) diff --git a/types/context.go b/types/context.go index 6d326fb73f19..35030dad9a96 100644 --- a/types/context.go +++ b/types/context.go @@ -6,6 +6,7 @@ import ( "github.com/gogo/protobuf/proto" abci "github.com/tendermint/tendermint/abci/types" + tmbytes "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -25,6 +26,7 @@ type Context struct { ctx context.Context ms MultiStore header tmproto.Header + headerHash tmbytes.HexBytes chainID string txBytes []byte logger log.Logger @@ -63,6 +65,13 @@ func (c Context) BlockHeader() tmproto.Header { return *msg } +// HeaderHash returns a copy of the header hash obtained during abci.RequestBeginBlock +func (c Context) HeaderHash() tmbytes.HexBytes { + hash := make([]byte, len(c.headerHash)) + copy(hash, c.headerHash) + return hash +} + func (c Context) ConsensusParams() *abci.ConsensusParams { return proto.Clone(c.consParams).(*abci.ConsensusParams) } @@ -104,6 +113,15 @@ func (c Context) WithBlockHeader(header tmproto.Header) Context { return c } +// WithHeaderHash returns a Context with an updated tendermint block header hash. +func (c Context) WithHeaderHash(hash []byte) Context { + temp := make([]byte, len(hash)) + copy(temp, hash) + + c.headerHash = temp + return c +} + // WithBlockTime returns a Context with an updated tendermint block header time in UTC time func (c Context) WithBlockTime(newTime time.Time) Context { newHeader := c.BlockHeader() diff --git a/types/context_test.go b/types/context_test.go index 018bd6a25792..88b6dab6ba19 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -103,6 +103,7 @@ func (s *contextTestSuite) TestContextWithCustom() { meter := types.NewGasMeter(10000) blockGasMeter := types.NewGasMeter(20000) minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)} + headerHash := []byte("headerHash") ctx = types.NewContext(nil, header, ischeck, logger) s.Require().Equal(header, ctx.BlockHeader()) @@ -114,7 +115,8 @@ func (s *contextTestSuite) TestContextWithCustom() { WithVoteInfos(voteinfos). WithGasMeter(meter). WithMinGasPrices(minGasPrices). - WithBlockGasMeter(blockGasMeter) + WithBlockGasMeter(blockGasMeter). + WithHeaderHash(headerHash) s.Require().Equal(height, ctx.BlockHeight()) s.Require().Equal(chainid, ctx.ChainID()) s.Require().Equal(ischeck, ctx.IsCheckTx()) @@ -124,6 +126,7 @@ func (s *contextTestSuite) TestContextWithCustom() { s.Require().Equal(meter, ctx.GasMeter()) s.Require().Equal(minGasPrices, ctx.MinGasPrices()) s.Require().Equal(blockGasMeter, ctx.BlockGasMeter()) + s.Require().Equal(headerHash, ctx.HeaderHash().Bytes()) s.Require().False(ctx.WithIsCheckTx(false).IsCheckTx()) // test IsReCheckTx diff --git a/types/decimal.go b/types/decimal.go index 6db1f587de7a..36b65bd983b7 100644 --- a/types/decimal.go +++ b/types/decimal.go @@ -80,7 +80,7 @@ func precisionMultiplier(prec int64) *big.Int { return precisionMultipliers[prec] } -//______________________________________________________________________________________________ +// ______________________________________________________________________________________________ // create a new Dec from integer assuming whole number func NewDec(i int64) Dec { @@ -198,8 +198,7 @@ func MustNewDecFromStr(s string) Dec { return dec } -//______________________________________________________________________________________________ -//nolint +// ______________________________________________________________________________________________ func (d Dec) IsNil() bool { return d.i == nil } // is decimal nil func (d Dec) IsZero() bool { return (d.i).Sign() == 0 } // is equal to zero func (d Dec) IsNegative() bool { return (d.i).Sign() == -1 } // is negative @@ -564,7 +563,7 @@ func (d Dec) RoundInt() Int { return NewIntFromBigInt(chopPrecisionAndRoundNonMutative(d.i)) } -//___________________________________________________________________________________ +// ___________________________________________________________________________________ // similar to chopPrecisionAndRound, but always rounds down func chopPrecisionAndTruncate(d *big.Int) *big.Int { @@ -615,7 +614,7 @@ func (d Dec) Ceil() Dec { return NewDecFromBigInt(quo.Add(quo, oneInt)) } -//___________________________________________________________________________________ +// ___________________________________________________________________________________ // MaxSortableDec is the largest Dec that can be passed into SortableDecBytes() // Its negative form is the least Dec that can be passed in. @@ -651,7 +650,7 @@ func SortableDecBytes(dec Dec) []byte { return []byte(fmt.Sprintf(fmt.Sprintf("%%0%ds", Precision*2+1), dec.String())) } -//___________________________________________________________________________________ +// ___________________________________________________________________________________ // reuse nil values var nilJSON []byte @@ -761,7 +760,7 @@ func (dp DecProto) String() string { return dp.Dec.String() } -//___________________________________________________________________________________ +// ___________________________________________________________________________________ // helpers // test if two decimal arrays are equal diff --git a/types/decimal_test.go b/types/decimal_test.go index 3eb86d8ec6ae..dae0935febd2 100644 --- a/types/decimal_test.go +++ b/types/decimal_test.go @@ -29,7 +29,7 @@ func (s *decimalTestSuite) mustNewDecFromStr(str string) (d sdk.Dec) { return d } -//_______________________________________ +// _______________________________________ func (s *decimalTestSuite) TestNewDecFromStr() { largeBigInt, success := new(big.Int).SetString("3144605511029693144278234343371835", 10) diff --git a/types/errors/errors.go b/types/errors/errors.go index 1aa68816ccbf..026f5f569b41 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -15,7 +15,6 @@ const UndefinedCodespace = "undefined" var ( // errInternal should never be exposed, but we reserve this code for non-specified errors - //nolint errInternal = Register(UndefinedCodespace, 1, "internal") // ErrTxDecode is returned if we cannot parse a transaction diff --git a/types/events.go b/types/events.go index 5a2bf3af4b08..27a0017635af 100644 --- a/types/events.go +++ b/types/events.go @@ -223,6 +223,11 @@ func toBytes(i interface{}) []byte { // Common event types and attribute keys var ( + EventTypeTx = "tx" + + AttributeKeyAccountSequence = "acc_seq" + AttributeKeySignature = "signature" + EventTypeMessage = "message" AttributeKeyAction = "action" diff --git a/types/module/module.go b/types/module/module.go index 2379c93d5ebd..5b47b8c84815 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -42,7 +42,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -//__________________________________________________________________________________________ +// __________________________________________________________________________________________ // AppModuleBasic is the standard form for basic non-dependant elements of an application module. type AppModuleBasic interface { @@ -145,7 +145,7 @@ func (bm BasicManager) AddQueryCommands(rootQueryCmd *cobra.Command) { } } -//_________________________________________________________ +// _________________________________________________________ // AppModuleGenesis is the standard form for an application module genesis functions type AppModuleGenesis interface { @@ -179,7 +179,7 @@ type AppModule interface { EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate } -//___________________________ +// ___________________________ // GenesisOnlyAppModule is an AppModule that only has import/export functionality type GenesisOnlyAppModule struct { @@ -216,7 +216,7 @@ func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []ab return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // Manager defines a module manager that provides the high level utility for managing and executing // operations for a group of modules diff --git a/types/simulation/config.go b/types/simulation/config.go index 58a39bb17d5b..8bad709545c9 100644 --- a/types/simulation/config.go +++ b/types/simulation/config.go @@ -6,8 +6,8 @@ type Config struct { ParamsFile string // custom simulation params file which overrides any random params; cannot be used with genesis ExportParamsPath string // custom file path to save the exported params JSON - ExportParamsHeight int //height to which export the randomly generated params - ExportStatePath string //custom file path to save the exported app state JSON + ExportParamsHeight int // height to which export the randomly generated params + ExportStatePath string // custom file path to save the exported app state JSON ExportStatsPath string // custom file path to save the exported simulation statistics JSON Seed int64 // simulation random seed diff --git a/types/simulation/types.go b/types/simulation/types.go index f541b1d764de..090978bf6e15 100644 --- a/types/simulation/types.go +++ b/types/simulation/types.go @@ -114,7 +114,7 @@ func (om OperationMsg) LogEvent(eventLogger func(route, op, evResult string)) { eventLogger(om.Route, om.Name, pass) } -//________________________________________________________________________ +// ________________________________________________________________________ // FutureOperation is an operation which will be ran at the beginning of the // provided BlockHeight. If both a BlockHeight and BlockTime are specified, it diff --git a/types/uint.go b/types/uint.go index 2305d7386728..a42c78395ed6 100644 --- a/types/uint.go +++ b/types/uint.go @@ -207,7 +207,7 @@ func (u *Uint) Size() int { func (u Uint) MarshalAmino() ([]byte, error) { return u.Marshal() } func (u *Uint) UnmarshalAmino(bz []byte) error { return u.Unmarshal(bz) } -//__________________________________________________________________________ +// __________________________________________________________________________ // UintOverflow returns true if a given unsigned integer overflows and false // otherwise. diff --git a/version/version.go b/version/version.go index a179b37fe31b..cfb37683f12e 100644 --- a/version/version.go +++ b/version/version.go @@ -36,26 +36,44 @@ var ( BuildTags = "" ) +func getSDKVersion() string { + deps, ok := debug.ReadBuildInfo() + if !ok { + return "unable to read deps" + } + var sdkVersion string + for _, dep := range deps.Deps { + if dep.Path == "github.com/cosmos/cosmos-sdk" { + sdkVersion = dep.Version + } + } + + return sdkVersion +} + // Info defines the application version information. type Info struct { - Name string `json:"name" yaml:"name"` - AppName string `json:"server_name" yaml:"server_name"` - Version string `json:"version" yaml:"version"` - GitCommit string `json:"commit" yaml:"commit"` - BuildTags string `json:"build_tags" yaml:"build_tags"` - GoVersion string `json:"go" yaml:"go"` - BuildDeps []buildDep `json:"build_deps" yaml:"build_deps"` + Name string `json:"name" yaml:"name"` + AppName string `json:"server_name" yaml:"server_name"` + Version string `json:"version" yaml:"version"` + GitCommit string `json:"commit" yaml:"commit"` + BuildTags string `json:"build_tags" yaml:"build_tags"` + GoVersion string `json:"go" yaml:"go"` + BuildDeps []buildDep `json:"build_deps" yaml:"build_deps"` + CosmosSdkVersion string `json:"cosmos_sdk_version" yaml:"cosmos_sdk_version"` } func NewInfo() Info { + sdkVersion := getSDKVersion() return Info{ - Name: Name, - AppName: AppName, - Version: Version, - GitCommit: Commit, - BuildTags: BuildTags, - GoVersion: fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH), - BuildDeps: depsFromBuildInfo(), + Name: Name, + AppName: AppName, + Version: Version, + GitCommit: Commit, + BuildTags: BuildTags, + GoVersion: fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH), + BuildDeps: depsFromBuildInfo(), + CosmosSdkVersion: sdkVersion, } } diff --git a/version/version_test.go b/version/version_test.go index 87608cfdbb97..ccfbf189d585 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -25,12 +25,13 @@ build tags: func TestInfo_String(t *testing.T) { info := version.Info{ - Name: "testapp", - AppName: "testappd", - Version: "1.0.0", - GitCommit: "1b78457135a4104bc3af97f20654d49e2ea87454", - BuildTags: "netgo,ledger", - GoVersion: "go version go1.14 linux/amd64", + Name: "testapp", + AppName: "testappd", + Version: "1.0.0", + GitCommit: "1b78457135a4104bc3af97f20654d49e2ea87454", + BuildTags: "netgo,ledger", + GoVersion: "go version go1.14 linux/amd64", + CosmosSdkVersion: "0.42.5", } want := `testapp: 1.0.0 git commit: 1b78457135a4104bc3af97f20654d49e2ea87454 diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 79fbbcdc676a..6aa0c2a345f9 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -2,6 +2,7 @@ package ante import ( "bytes" + "encoding/base64" "encoding/hex" "fmt" @@ -90,6 +91,34 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b spkd.ak.SetAccount(ctx, acc) } + // Also emit the following events, so that txs can be indexed by these + // indices: + // - signature (via `tx.signature=''`), + // - concat(address,"/",sequence) (via `tx.acc_seq='cosmos1abc...def/42'`). + sigs, err := sigTx.GetSignaturesV2() + if err != nil { + return ctx, err + } + + var events sdk.Events + for i, sig := range sigs { + events = append(events, sdk.NewEvent(sdk.EventTypeTx, + sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signers[i], sig.Sequence)), + )) + + sigBzs, err := signatureDataToBz(sig.Data) + if err != nil { + return ctx, err + } + for _, sigBz := range sigBzs { + events = append(events, sdk.NewEvent(sdk.EventTypeTx, + sdk.NewAttribute(sdk.AttributeKeySignature, base64.StdEncoding.EncodeToString(sigBz)), + )) + } + } + + ctx.EventManager().EmitEvents(events) + return next(ctx, tx, simulate) } @@ -436,3 +465,42 @@ func CountSubKeys(pub cryptotypes.PubKey) int { return numKeys } + +// signatureDataToBz converts a SignatureData into raw bytes signature. +// For SingleSignatureData, it returns the signature raw bytes. +// For MultiSignatureData, it returns an array of all individual signatures, +// as well as the aggregated signature. +func signatureDataToBz(data signing.SignatureData) ([][]byte, error) { + if data == nil { + return nil, fmt.Errorf("got empty SignatureData") + } + + switch data := data.(type) { + case *signing.SingleSignatureData: + return [][]byte{data.Signature}, nil + case *signing.MultiSignatureData: + sigs := [][]byte{} + var err error + + for _, d := range data.Signatures { + nestedSigs, err := signatureDataToBz(d) + if err != nil { + return nil, err + } + sigs = append(sigs, nestedSigs...) + } + + multisig := cryptotypes.MultiSignature{ + Signatures: sigs, + } + aggregatedSig, err := multisig.Marshal() + if err != nil { + return nil, err + } + sigs = append(sigs, aggregatedSig) + + return sigs, nil + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unexpected signature data type %T", data) + } +} diff --git a/x/auth/client/cli/cli_test.go b/x/auth/client/cli/cli_test.go index 2b305e809256..c78e03a86a29 100644 --- a/x/auth/client/cli/cli_test.go +++ b/x/auth/client/cli/cli_test.go @@ -4,6 +4,7 @@ package cli_test import ( "context" + "encoding/base64" "encoding/json" "fmt" "io/ioutil" @@ -78,11 +79,17 @@ func (s *IntegrationTestSuite) TearDownSuite() { func (s *IntegrationTestSuite) TestCLIValidateSignatures() { val := s.network.Validators[0] - res := s.createBankMsg(val, val.Address) + sendTokens := sdk.NewCoins( + sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(10)), + sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))) + + res, err := s.createBankMsg(val, val.Address, sendTokens, + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) + s.Require().NoError(err) // write unsigned tx to file unsignedTx := testutil.WriteToNewTempFile(s.T(), res.String()) - res, err := authtest.TxSignExec(val.ClientCtx, val.Address, unsignedTx.Name()) + res, err = authtest.TxSignExec(val.ClientCtx, val.Address, unsignedTx.Name()) s.Require().NoError(err) signedTx, err := val.ClientCtx.TxConfig.TxJSONDecoder()(res.Bytes()) s.Require().NoError(err) @@ -104,7 +111,15 @@ func (s *IntegrationTestSuite) TestCLIValidateSignatures() { func (s *IntegrationTestSuite) TestCLISignBatch() { val := s.network.Validators[0] - generatedStd := s.createBankMsg(val, val.Address) + var sendTokens = sdk.NewCoins( + sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(10)), + sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)), + ) + + generatedStd, err := s.createBankMsg(val, val.Address, + sendTokens, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) + s.Require().NoError(err) + outputFile := testutil.WriteToNewTempFile(s.T(), strings.Repeat(generatedStd.String(), 3)) val.ClientCtx.HomeDir = strings.Replace(val.ClientCtx.HomeDir, "simd", "simcli", 1) @@ -136,7 +151,13 @@ func (s *IntegrationTestSuite) TestCLISign_AminoJSON() { require := s.Require() val1 := s.network.Validators[0] txCfg := val1.ClientCtx.TxConfig - txBz := s.createBankMsg(val1, val1.Address) + var sendTokens = sdk.NewCoins( + sdk.NewCoin(fmt.Sprintf("%stoken", val1.Moniker), sdk.NewInt(10)), + sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)), + ) + txBz, err := s.createBankMsg(val1, val1.Address, + sendTokens, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) + require.NoError(err) fileUnsigned := testutil.WriteToNewTempFile(s.T(), txBz.String()) chainFlag := fmt.Sprintf("--%s=%s", flags.FlagChainID, val1.ClientCtx.ChainID) sigOnlyFlag := "--signature-only" @@ -224,7 +245,7 @@ func checkSignatures(require *require.Assertions, txCfg client.TxConfig, output } } -func (s *IntegrationTestSuite) TestCLIQueryTxCmd() { +func (s *IntegrationTestSuite) TestCLIQueryTxCmdByHash() { val := s.network.Validators[0] account2, err := val.ClientCtx.Keyring.Key("newAccount2") @@ -271,17 +292,20 @@ func (s *IntegrationTestSuite) TestCLIQueryTxCmd() { expectErr bool rawLogContains string }{ + { + "not enough args", + []string{}, + true, "", + }, { "with invalid hash", []string{"somethinginvalid", fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, - true, - "", + true, "", }, { "with valid and not existing hash", []string{"C7E7D3A86A17AB3A321172239F3B61357937AF0F25D9FA4D2F4DCCAD9B0D7747", fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, - true, - "", + true, "", }, { "happy case (legacy Msg)", @@ -318,6 +342,120 @@ func (s *IntegrationTestSuite) TestCLIQueryTxCmd() { } } +func (s *IntegrationTestSuite) TestCLIQueryTxCmdByEvents() { + val := s.network.Validators[0] + + account2, err := val.ClientCtx.Keyring.Key("newAccount2") + s.Require().NoError(err) + + sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10) + + // Send coins. + out, err := s.createBankMsg( + val, account2.GetAddress(), + sdk.NewCoins(sendTokens), + ) + s.Require().NoError(err) + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + s.Require().NoError(s.network.WaitForNextBlock()) + + // Query the tx by hash to get the inner tx. + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcli.QueryTxCmd(), []string{txRes.TxHash, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + protoTx := txRes.GetTx().(*tx.Tx) + + testCases := []struct { + name string + args []string + expectErr bool + expectErrStr string + }{ + { + "invalid --type", + []string{ + fmt.Sprintf("--type=%s", "foo"), + "bar", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, "unknown --type value foo", + }, + { + "--type=acc_seq with no addr+seq", + []string{ + "--type=acc_seq", + "", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, "`acc_seq` type takes an argument '/'", + }, + { + "non-existing addr+seq combo", + []string{ + "--type=acc_seq", + "foobar", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, "found no txs matching given address and sequence combination", + }, + { + "addr+seq happy case", + []string{ + "--type=acc_seq", + fmt.Sprintf("%s/%d", val.Address, protoTx.AuthInfo.SignerInfos[0].Sequence), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + false, "", + }, + { + "--type=signature with no signature", + []string{ + "--type=signature", + "", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, "argument should be comma-separated signatures", + }, + { + "non-existing signatures", + []string{ + "--type=signature", + "foo", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, "found no txs matching given signatures", + }, + { + "with --signatures happy case", + []string{ + "--type=signature", + base64.StdEncoding.EncodeToString(protoTx.Signatures[0]), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + false, "", + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := authcli.QueryTxCmd() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.expectErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expectErrStr) + } else { + var result sdk.TxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &result)) + s.Require().NotNil(result.Height) + } + }) + } +} + func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { val1 := s.network.Validators[0] @@ -732,7 +870,7 @@ func (s *IntegrationTestSuite) TestCLIMultisign() { sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String()) - // Sign with account1 + // Sign with account2 account2Signature, err := authtest.TxSignExec(val1.ClientCtx, account2.GetAddress(), multiGeneratedTxFile.Name(), "--multisig", multisigInfo.GetAddress().String()) s.Require().NoError(err) @@ -1136,22 +1274,15 @@ func (s *IntegrationTestSuite) TestSignWithMultiSigners_AminoJSON() { require.Equal(sdk.NewCoins(val0Coin, val1Coin), queryRes.Balances) } -func (s *IntegrationTestSuite) createBankMsg(val *network.Validator, toAddr sdk.AccAddress) testutil.BufferWriter { - res, err := bankcli.MsgSendExec( - val.ClientCtx, - val.Address, - toAddr, - sdk.NewCoins( - sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(10)), - sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)), - ), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), +func (s *IntegrationTestSuite) createBankMsg(val *network.Validator, toAddr sdk.AccAddress, amount sdk.Coins, extraFlags ...string) (testutil.BufferWriter, error) { + flags := []string{fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - ) - s.Require().NoError(err) - return res + fmt.Sprintf("--%s=%s", flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + } + + flags = append(flags, extraFlags...) + return bankcli.MsgSendExec(val.ClientCtx, val.Address, toAddr, amount, flags...) } func TestIntegrationTestSuite(t *testing.T) { diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index 2590858b4c20..b019749bd6b2 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -11,6 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/version" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" @@ -19,6 +21,11 @@ import ( const ( flagEvents = "events" + flagType = "type" + + typeHash = "hash" + typeAccSeq = "acc_seq" + typeSig = "signature" eventFormat = "{eventType}.{eventAttribute}={value}" ) @@ -179,28 +186,110 @@ $ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator // QueryTxCmd implements the default command for a tx query. func QueryTxCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "tx [hash]", - Short: "Query for a transaction by hash in a committed block", - Args: cobra.ExactArgs(1), + Use: "tx --type=[hash|acc_seq|signature] [hash|acc_seq|signature]", + Short: "Query for a transaction by hash, \"/\" combination or comma-separated signatures in a committed block", + Long: strings.TrimSpace(fmt.Sprintf(` +Example: +$ %s query tx +$ %s query tx --%s=%s / +$ %s query tx --%s=%s , +`, + version.AppName, + version.AppName, flagType, typeAccSeq, + version.AppName, flagType, typeSig)), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - output, err := authclient.QueryTx(clientCtx, args[0]) - if err != nil { - return err - } - if output.Empty() { - return fmt.Errorf("no transaction found with hash %s", args[0]) - } + typ, _ := cmd.Flags().GetString(flagType) + + switch typ { + case typeHash: + { + if args[0] == "" { + return fmt.Errorf("argument should be a tx hash") + } + + // If hash is given, then query the tx by hash. + output, err := authclient.QueryTx(clientCtx, args[0]) + if err != nil { + return err + } - return clientCtx.PrintProto(output) + if output.Empty() { + return fmt.Errorf("no transaction found with hash %s", args[0]) + } + + return clientCtx.PrintProto(output) + } + case typeSig: + { + sigParts, err := parseSigArgs(args) + if err != nil { + return err + } + tmEvents := make([]string, len(sigParts)) + for i, sig := range sigParts { + tmEvents[i] = fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) + } + + txs, err := authclient.QueryTxsByEvents(clientCtx, tmEvents, rest.DefaultPage, query.DefaultLimit, "") + if err != nil { + return err + } + if len(txs.Txs) == 0 { + return fmt.Errorf("found no txs matching given signatures") + } + if len(txs.Txs) > 1 { + // This case means there's a bug somewhere else in the code. Should not happen. + return errors.Wrapf(errors.ErrLogic, "found %d txs matching given signatures", len(txs.Txs)) + } + + return clientCtx.PrintProto(txs.Txs[0]) + } + case typeAccSeq: + { + if args[0] == "" { + return fmt.Errorf("`acc_seq` type takes an argument '/'") + } + + tmEvents := []string{ + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeyAccountSequence, args[0]), + } + txs, err := authclient.QueryTxsByEvents(clientCtx, tmEvents, rest.DefaultPage, query.DefaultLimit, "") + if err != nil { + return err + } + if len(txs.Txs) == 0 { + return fmt.Errorf("found no txs matching given address and sequence combination") + } + if len(txs.Txs) > 1 { + // This case means there's a bug somewhere else in the code. Should not happen. + return fmt.Errorf("found %d txs matching given address and sequence combination", len(txs.Txs)) + } + + return clientCtx.PrintProto(txs.Txs[0]) + } + default: + return fmt.Errorf("unknown --%s value %s", flagType, typ) + } }, } flags.AddQueryFlagsToCmd(cmd) + cmd.Flags().String(flagType, typeHash, fmt.Sprintf("The type to be used when querying tx, can be one of \"%s\", \"%s\", \"%s\"", typeHash, typeAccSeq, typeSig)) return cmd } + +// parseSigArgs parses comma-separated signatures from the CLI arguments. +func parseSigArgs(args []string) ([]string, error) { + if len(args) != 1 || args[0] == "" { + return nil, fmt.Errorf("argument should be comma-separated signatures") + } + + return strings.Split(args[0], ","), nil +} diff --git a/x/auth/client/cli/query_test.go b/x/auth/client/cli/query_test.go new file mode 100644 index 000000000000..0168d3008179 --- /dev/null +++ b/x/auth/client/cli/query_test.go @@ -0,0 +1,32 @@ +package cli + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseSigs(t *testing.T) { + cases := []struct { + name string + args []string + expErr bool + expNumSigs int + }{ + {"no args", []string{}, true, 0}, + {"empty args", []string{""}, true, 0}, + {"too many args", []string{"foo", "bar"}, true, 0}, + {"1 sig", []string{"foo"}, false, 1}, + {"3 sigs", []string{"foo,bar,baz"}, false, 3}, + } + + for _, tc := range cases { + sigs, err := parseSigArgs(tc.args) + if tc.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.expNumSigs, len(sigs)) + } + } +} diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index cd5c687eac6b..1b7a68a9c729 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -108,6 +108,10 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { return err } + if txFactory.ChainID() == "" { + return fmt.Errorf("set the chain id with either the --chain-id flag or config file") + } + signingData := signing.SignerData{ ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), diff --git a/x/auth/legacy/v034/types.go b/x/auth/legacy/v034/types.go index c5df671017b2..83fa2d36eace 100644 --- a/x/auth/legacy/v034/types.go +++ b/x/auth/legacy/v034/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v034 import ( diff --git a/x/auth/legacy/v036/migrate.go b/x/auth/legacy/v036/migrate.go index c651df6994d8..2ab4aa14379b 100644 --- a/x/auth/legacy/v036/migrate.go +++ b/x/auth/legacy/v036/migrate.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/auth/legacy/v036/types.go b/x/auth/legacy/v036/types.go index 2490f4baa22e..908165f26505 100644 --- a/x/auth/legacy/v036/types.go +++ b/x/auth/legacy/v036/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v034" diff --git a/x/auth/legacy/v038/types.go b/x/auth/legacy/v038/types.go index e9977c1d2966..b7dedf003e13 100644 --- a/x/auth/legacy/v038/types.go +++ b/x/auth/legacy/v038/types.go @@ -1,7 +1,6 @@ package v038 // DONTCOVER -// nolint import ( "bytes" diff --git a/x/auth/legacy/v039/types.go b/x/auth/legacy/v039/types.go index 55c3014eb7f0..3de576f27ffa 100644 --- a/x/auth/legacy/v039/types.go +++ b/x/auth/legacy/v039/types.go @@ -1,7 +1,6 @@ package v039 // DONTCOVER -// nolint import ( "bytes" diff --git a/x/auth/module.go b/x/auth/module.go index 73aa9a1066a9..7a9e6c749f94 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -85,7 +85,7 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the auth module. type AppModule struct { @@ -156,7 +156,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/auth/testutil/suite.go b/x/auth/testutil/suite.go index f8002e68e4e6..23c59b7fcfba 100644 --- a/x/auth/testutil/suite.go +++ b/x/auth/testutil/suite.go @@ -16,7 +16,7 @@ import ( ) // TxConfigTestSuite provides a test suite that can be used to test that a TxConfig implementation is correct -//nolint:golint // type name will be used as tx.TxConfigTestSuite by other packages, and that stutters; consider calling this GeneratorTestSuite +// type name will be used as tx.TxConfigTestSuite by other packages, and that stutters; consider calling this GeneratorTestSuite type TxConfigTestSuite struct { suite.Suite TxConfig client.TxConfig diff --git a/x/auth/types/account_retriever.go b/x/auth/types/account_retriever.go index f84c744188ff..792524fff017 100644 --- a/x/auth/types/account_retriever.go +++ b/x/auth/types/account_retriever.go @@ -32,7 +32,6 @@ func (ar AccountRetriever) GetAccount(clientCtx client.Context, addr sdk.AccAddr // GetAccountWithHeight queries for an account given an address. Returns the // height of the query with the account. An error is returned if the query // or decoding fails. -//nolint:interfacer func (ar AccountRetriever) GetAccountWithHeight(clientCtx client.Context, addr sdk.AccAddress) (client.Account, int64, error) { var header metadata.MD diff --git a/x/auth/types/params.go b/x/auth/types/params.go index 710ee963b4a3..13db369d2353 100644 --- a/x/auth/types/params.go +++ b/x/auth/types/params.go @@ -48,7 +48,6 @@ func ParamKeyTable() paramtypes.KeyTable { // ParamSetPairs implements the ParamSet interface and returns all the key/value pairs // pairs of auth module's parameters. -// nolint func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyMaxMemoCharacters, &p.MaxMemoCharacters, validateMaxMemoCharacters), diff --git a/x/bank/keeper/genesis.go b/x/bank/keeper/genesis.go index d30415c6a285..c70dee585c6c 100644 --- a/x/bank/keeper/genesis.go +++ b/x/bank/keeper/genesis.go @@ -20,7 +20,7 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { panic(err) } - if err := k.SetBalances(ctx, addr, balance.Coins); err != nil { + if err := k.initBalances(ctx, addr, balance.Coins); err != nil { panic(fmt.Errorf("error on setting balances %w", err)) } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index c1000b7d3025..59668463c7d1 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -258,6 +258,28 @@ func (k BaseSendKeeper) SetBalances(ctx sdk.Context, addr sdk.AccAddress, balanc return nil } +// initBalances sets the balance (multiple coins) for an account by address. +// An error is returned upon failure. +func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balances sdk.Coins) error { + store := ctx.KVStore(k.storeKey) + balancesStore := prefix.NewStore(store, types.BalancesPrefix) + accountStore := prefix.NewStore(balancesStore, addr.Bytes()) + for i := range balances { + balance := balances[i] + if !balance.IsValid() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, balance.String()) + } + + // Bank invariants require to not store zero balances. + if !balance.IsZero() { + bz := k.cdc.MustMarshalBinaryBare(&balance) + accountStore.Set([]byte(balance.Denom), bz) + } + } + + return nil +} + // SetBalance sets the coin balance for an account by address. func (k BaseSendKeeper) SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) error { if !balance.IsValid() { diff --git a/x/bank/legacy/v036/types.go b/x/bank/legacy/v036/types.go index 1de8ffb9b71f..ada368404855 100644 --- a/x/bank/legacy/v036/types.go +++ b/x/bank/legacy/v036/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/bank/legacy/v038/types.go b/x/bank/legacy/v038/types.go index e67640bf2b12..eba8d3518ca1 100644 --- a/x/bank/legacy/v038/types.go +++ b/x/bank/legacy/v038/types.go @@ -1,7 +1,6 @@ package v038 // DONTCOVER -// nolint const ( ModuleName = "bank" diff --git a/x/bank/module.go b/x/bank/module.go index f271fa21975c..c0fb03999d05 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -86,7 +86,7 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the bank module. type AppModule struct { @@ -160,7 +160,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/bank/simulation/operations.go b/x/bank/simulation/operations.go index 9fcc80f0fe45..632ed11f5ffe 100644 --- a/x/bank/simulation/operations.go +++ b/x/bank/simulation/operations.go @@ -81,7 +81,6 @@ func SimulateMsgSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Operatio } // sendMsgSend sends a transaction with a MsgSend from a provided random account. -// nolint: interfacer func sendMsgSend( r *rand.Rand, app *baseapp.BaseApp, bk keeper.Keeper, ak types.AccountKeeper, msg *types.MsgSend, ctx sdk.Context, chainID string, privkeys []cryptotypes.PrivKey, @@ -222,8 +221,6 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope } // sendMsgMultiSend sends a transaction with a MsgMultiSend from a provided random -// account. -// nolint: interfacer func sendMsgMultiSend( r *rand.Rand, app *baseapp.BaseApp, bk keeper.Keeper, ak types.AccountKeeper, msg *types.MsgMultiSend, ctx sdk.Context, chainID string, privkeys []cryptotypes.PrivKey, @@ -289,7 +286,6 @@ func sendMsgMultiSend( // randomSendFields returns the sender and recipient simulation accounts as well // as the transferred amount. -// nolint: interfacer func randomSendFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, bk keeper.Keeper, ak types.AccountKeeper, ) (simtypes.Account, simtypes.Account, sdk.Coins, bool) { diff --git a/x/bank/simulation/params.go b/x/bank/simulation/params.go index c3da182205b7..222f88acaba2 100644 --- a/x/bank/simulation/params.go +++ b/x/bank/simulation/params.go @@ -23,7 +23,7 @@ func ParamChanges(r *rand.Rand) []simtypes.ParamChange { if err != nil { panic(err) } - return fmt.Sprintf("%s", paramsBytes) + return string(paramsBytes) }, ), simulation.NewSimParamChange(types.ModuleName, string(types.KeyDefaultSendEnabled), diff --git a/x/capability/capability_test.go b/x/capability/capability_test.go new file mode 100644 index 000000000000..a197f00dd831 --- /dev/null +++ b/x/capability/capability_test.go @@ -0,0 +1,97 @@ +package capability_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/capability" + "github.com/cosmos/cosmos-sdk/x/capability/keeper" + "github.com/cosmos/cosmos-sdk/x/capability/types" +) + +type CapabilityTestSuite struct { + suite.Suite + + cdc codec.Marshaler + ctx sdk.Context + app *simapp.SimApp + keeper *keeper.Keeper + module module.AppModule +} + +func (suite *CapabilityTestSuite) SetupTest() { + checkTx := false + app := simapp.Setup(checkTx) + cdc := app.AppCodec() + + // create new keeper so we can define custom scoping before init and seal + keeper := keeper.NewKeeper(cdc, app.GetKey(types.StoreKey), app.GetMemKey(types.MemStoreKey)) + + suite.app = app + suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1}) + suite.keeper = keeper + suite.cdc = cdc + suite.module = capability.NewAppModule(cdc, *keeper) +} + +// The following test case mocks a specific bug discovered in https://github.com/cosmos/cosmos-sdk/issues/9800 +// and ensures that the current code successfully fixes the issue. +func (suite *CapabilityTestSuite) TestInitializeMemStore() { + sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) + + cap1, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap1) + + // mock statesync by creating new keeper that shares persistent state but loses in-memory map + newKeeper := keeper.NewKeeper(suite.cdc, suite.app.GetKey(types.StoreKey), suite.app.GetMemKey("testing")) + newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName) + + // Mock App startup + ctx := suite.app.BaseApp.NewUncachedContext(false, tmproto.Header{}) + newKeeper.InitializeAndSeal(ctx) + suite.Require().False(newKeeper.IsInitialized(ctx), "memstore initialized flag set before BeginBlock") + + // Mock app beginblock and ensure that no gas has been consumed and memstore is initialized + ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}).WithBlockGasMeter(sdk.NewGasMeter(50)) + prevGas := ctx.BlockGasMeter().GasConsumed() + restartedModule := capability.NewAppModule(suite.cdc, *newKeeper) + restartedModule.BeginBlock(ctx, abci.RequestBeginBlock{}) + suite.Require().True(newKeeper.IsInitialized(ctx), "memstore initialized flag not set") + gasUsed := ctx.BlockGasMeter().GasConsumed() + + suite.Require().Equal(prevGas, gasUsed, "beginblocker consumed gas during execution") + + // Mock the first transaction getting capability and subsequently failing + // by using a cached context and discarding all cached writes. + cacheCtx, _ := ctx.CacheContext() + _, ok := newSk1.GetCapability(cacheCtx, "transfer") + suite.Require().True(ok) + + // Ensure that the second transaction can still receive capability even if first tx fails. + ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) + + cap1, ok = newSk1.GetCapability(ctx, "transfer") + suite.Require().True(ok) + + // Ensure the capabilities don't get reinitialized on next BeginBlock + // by testing to see if capability returns same pointer + // also check that initialized flag is still set + restartedModule.BeginBlock(ctx, abci.RequestBeginBlock{}) + recap, ok := newSk1.GetCapability(ctx, "transfer") + suite.Require().True(ok) + suite.Require().Equal(cap1, recap, "capabilities got reinitialized after second BeginBlock") + suite.Require().True(newKeeper.IsInitialized(ctx), "memstore initialized flag not set") +} + +func TestCapabilityTestSuite(t *testing.T) { + suite.Run(t, new(CapabilityTestSuite)) +} diff --git a/x/capability/genesis.go b/x/capability/genesis.go index ba8e09dcd375..2e9a11b994be 100644 --- a/x/capability/genesis.go +++ b/x/capability/genesis.go @@ -13,11 +13,12 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) panic(err) } - // set owners for each index and initialize capability + // set owners for each index for _, genOwner := range genState.Owners { k.SetOwners(ctx, genOwner.Index, genOwner.IndexOwners) - k.InitializeCapability(ctx, genOwner.Index, genOwner.IndexOwners) } + // initialize in-memory capabilities + k.InitMemStore(ctx) } // ExportGenesis returns the capability module's exported genesis. diff --git a/x/capability/genesis_test.go b/x/capability/genesis_test.go new file mode 100644 index 000000000000..34a09960e750 --- /dev/null +++ b/x/capability/genesis_test.go @@ -0,0 +1,59 @@ +package capability_test + +import ( + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/capability" + "github.com/cosmos/cosmos-sdk/x/capability/keeper" + "github.com/cosmos/cosmos-sdk/x/capability/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func (suite *CapabilityTestSuite) TestGenesis() { + sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) + sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) + + cap1, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap1) + + err = sk2.ClaimCapability(suite.ctx, cap1, "transfer") + suite.Require().NoError(err) + + cap2, err := sk2.NewCapability(suite.ctx, "ica") + suite.Require().NoError(err) + suite.Require().NotNil(cap2) + + genState := capability.ExportGenesis(suite.ctx, *suite.keeper) + + // create new app that does not share persistent or in-memory state + // and initialize app from exported genesis state above. + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + newApp := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + newKeeper := keeper.NewKeeper(suite.cdc, newApp.GetKey(types.StoreKey), newApp.GetMemKey(types.MemStoreKey)) + newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName) + newSk2 := newKeeper.ScopeToModule(stakingtypes.ModuleName) + deliverCtx, _ := newApp.BaseApp.NewUncachedContext(false, tmproto.Header{}).WithBlockGasMeter(sdk.NewInfiniteGasMeter()).CacheContext() + + capability.InitGenesis(deliverCtx, *newKeeper, *genState) + + // check that all previous capabilities exist in new app after InitGenesis + sk1Cap1, ok := newSk1.GetCapability(deliverCtx, "transfer") + suite.Require().True(ok, "could not get first capability after genesis on first ScopedKeeper") + suite.Require().Equal(*cap1, *sk1Cap1, "capability values not equal on first ScopedKeeper") + + sk2Cap1, ok := newSk2.GetCapability(deliverCtx, "transfer") + suite.Require().True(ok, "could not get first capability after genesis on first ScopedKeeper") + suite.Require().Equal(*cap1, *sk2Cap1, "capability values not equal on first ScopedKeeper") + + sk2Cap2, ok := newSk2.GetCapability(deliverCtx, "ica") + suite.Require().True(ok, "could not get second capability after genesis on second ScopedKeeper") + suite.Require().Equal(*cap2, *sk2Cap2, "capability values not equal on second ScopedKeeper") +} diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 61de0338991c..4002c199a4fe 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -89,38 +89,58 @@ func (k *Keeper) ScopeToModule(moduleName string) ScopedKeeper { } } -// InitializeAndSeal loads all capabilities from the persistent KVStore into the -// in-memory store and seals the keeper to prevent further modules from creating -// a scoped keeper. InitializeAndSeal must be called once after the application -// state is loaded. +// InitializeAndSeal seals the keeper to prevent further modules from creating +// a scoped keeper. It also panics if the memory store is not of storetype `StoreTypeMemory`. func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { if k.sealed { panic("cannot initialize and seal an already sealed capability keeper") } - memStore := ctx.KVStore(k.memKey) + k.sealed = true +} + +// InitMemStore will initialize the memory store if it hasn't been initialized yet. +// The function is safe to be called multiple times. +// InitMemStore must be called every time the app starts before the keeper is used (so +// `BeginBlock` or `InitChain` - whichever is first). We need access to the store so we +// can't initialize it in a constructor. +func (k *Keeper) InitMemStore(ctx sdk.Context) { + // create context with no block gas meter to ensure we do not consume gas during local initialization logic. + noGasCtx := ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) + + memStore := noGasCtx.KVStore(k.memKey) memStoreType := memStore.GetStoreType() if memStoreType != sdk.StoreTypeMemory { panic(fmt.Sprintf("invalid memory store type; got %s, expected: %s", memStoreType, sdk.StoreTypeMemory)) } - prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixIndexCapability) - iterator := sdk.KVStorePrefixIterator(prefixStore, nil) + // check if memory store has not been initialized yet by checking if initialized flag is nil. + if !k.IsInitialized(noGasCtx) { + prefixStore := prefix.NewStore(noGasCtx.KVStore(k.storeKey), types.KeyPrefixIndexCapability) + iterator := sdk.KVStorePrefixIterator(prefixStore, nil) - // initialize the in-memory store for all persisted capabilities - defer iterator.Close() + // initialize the in-memory store for all persisted capabilities + defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - index := types.IndexFromKey(iterator.Key()) + for ; iterator.Valid(); iterator.Next() { + index := types.IndexFromKey(iterator.Key()) - var capOwners types.CapabilityOwners + var capOwners types.CapabilityOwners - k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &capOwners) - k.InitializeCapability(ctx, index, capOwners) + k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &capOwners) + k.InitializeCapability(noGasCtx, index, capOwners) + } + + // set the initialized flag so we don't rerun initialization logic + memStore.Set(types.KeyMemInitialized, []byte{1}) } +} - k.sealed = true +// IsInitialized returns true if the keeper is properly initialized, and false otherwise +func (k *Keeper) IsInitialized(ctx sdk.Context) bool { + memStore := ctx.KVStore(k.memKey) + return memStore.Get(types.KeyMemInitialized) != nil } // InitializeIndex sets the index to one (or greater) in InitChain according @@ -358,6 +378,7 @@ func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (*types.Capab // so we delete here to remove unnecessary values in map // TODO: Delete index correctly from capMap by storing some reverse lookup // in-memory map. Issue: https://github.com/cosmos/cosmos-sdk/issues/7805 + return nil, false } diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index e62176a72463..094b12811391 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -18,6 +19,7 @@ import ( type KeeperTestSuite struct { suite.Suite + cdc codec.Marshaler ctx sdk.Context app *simapp.SimApp keeper *keeper.Keeper @@ -34,6 +36,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.app = app suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1}) suite.keeper = keeper + suite.cdc = cdc } func (suite *KeeperTestSuite) TestInitializeAndSeal() { diff --git a/x/capability/module.go b/x/capability/module.go index 7957f57747d6..124712647e5d 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "math/rand" + "time" "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -14,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -136,8 +138,16 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json return cdc.MustMarshalJSON(genState) } -// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +// BeginBlocker will call InitMemStore to initialize the memory stores in the case +// that this is the first time the node is executing a block since restarting (wiping memory). +// In this case, the BeginBlocker method will reinitialize the memory stores locally, so that subsequent +// capability transactions will pass. +// Otherwise BeginBlocker performs a no-op. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + am.keeper.InitMemStore(ctx) +} // EndBlock executes all ABCI EndBlock logic respective to the capability module. It // returns no validator updates. diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index 5f171e28a7f4..aefd13ba2286 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -25,6 +25,9 @@ var ( // KeyPrefixIndexCapability defines a key prefix that stores index to capability // name mappings. KeyPrefixIndexCapability = []byte("capability_index") + + // KeyMemInitialized defines the key that stores the initialized flag in the memory store + KeyMemInitialized = []byte("mem_initialized") ) // RevCapabilityKey returns a reverse lookup key for a given module and capability diff --git a/x/crisis/handler_test.go b/x/crisis/handler_test.go index dcde377f6d42..c35af8ee8775 100644 --- a/x/crisis/handler_test.go +++ b/x/crisis/handler_test.go @@ -47,7 +47,7 @@ func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) { return app, ctx, addrs } -//____________________________________________________________________________ +// ____________________________________________________________________________ func TestHandleMsgVerifyInvariant(t *testing.T) { app, ctx, addrs := createTestApp() diff --git a/x/crisis/keeper/msg_server.go b/x/crisis/keeper/msg_server.go index 304f8b17243d..0b885825a01d 100644 --- a/x/crisis/keeper/msg_server.go +++ b/x/crisis/keeper/msg_server.go @@ -48,14 +48,14 @@ func (k Keeper) VerifyInvariant(goCtx context.Context, msg *types.MsgVerifyInvar // refund is required. // TODO uncomment the following code block with implementation of the circuit breaker - //// refund constant fee - //err := k.distrKeeper.DistributeFromFeePool(ctx, constantFee, msg.Sender) - //if err != nil { - //// if there are insufficient coins to refund, log the error, - //// but still halt the chain. - //logger := ctx.Logger().With("module", "x/crisis") - //logger.Error(fmt.Sprintf( - //"WARNING: insufficient funds to allocate to sender from fee pool, err: %s", err)) + // // refund constant fee + // err := k.distrKeeper.DistributeFromFeePool(ctx, constantFee, msg.Sender) + // if err != nil { + // // if there are insufficient coins to refund, log the error, + // // but still halt the chain. + // logger := ctx.Logger().With("module", "x/crisis") + // logger.Error(fmt.Sprintf( + // "WARNING: insufficient funds to allocate to sender from fee pool, err: %s", err)) //} // TODO replace with circuit breaker diff --git a/x/crisis/module.go b/x/crisis/module.go index 5d34c1ce28f9..4da832fd881a 100644 --- a/x/crisis/module.go +++ b/x/crisis/module.go @@ -80,7 +80,7 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the crisis module. type AppModule struct { diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index d62bcd21fa07..2e6a6eeb3953 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -24,7 +24,7 @@ var ( ) const ( - MaxMessagesPerTxDefault = 5 + MaxMessagesPerTxDefault = 0 ) // NewTxCmd returns a root CLI command handler for all x/distribution transaction commands. @@ -133,11 +133,12 @@ func NewWithdrawAllRewardsCmd() *cobra.Command { Short: "withdraw all delegations rewards for a delegator", Long: strings.TrimSpace( fmt.Sprintf(`Withdraw all rewards for a single delegator. +Note that if you use this command with --%[2]s=%[3]s or --%[2]s=%[4]s, the %[5]s flag will automatically be set to 0. Example: -$ %s tx distribution withdraw-all-rewards --from mykey +$ %[1]s tx distribution withdraw-all-rewards --from mykey `, - version.AppName, + version.AppName, flags.FlagBroadcastMode, flags.BroadcastSync, flags.BroadcastAsync, FlagMaxMessagesPerTx, ), ), Args: cobra.NoArgs, @@ -177,6 +178,11 @@ $ %s tx distribution withdraw-all-rewards --from mykey } chunkSize, _ := cmd.Flags().GetInt(FlagMaxMessagesPerTx) + if clientCtx.BroadcastMode != flags.BroadcastBlock && chunkSize > 0 { + return fmt.Errorf("cannot use broadcast mode %[1]s with %[2]s != 0", + clientCtx.BroadcastMode, FlagMaxMessagesPerTx) + } + return newSplitAndApply(tx.GenerateOrBroadcastTxCLI, clientCtx, cmd.Flags(), msgs, chunkSize) }, } diff --git a/x/distribution/legacy/v034/types.go b/x/distribution/legacy/v034/types.go index 3ef672f4af3b..4e8b209ad67b 100644 --- a/x/distribution/legacy/v034/types.go +++ b/x/distribution/legacy/v034/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v034 import ( diff --git a/x/distribution/legacy/v036/types.go b/x/distribution/legacy/v036/types.go index 1c43eb5acd2a..e6a5d9232414 100644 --- a/x/distribution/legacy/v036/types.go +++ b/x/distribution/legacy/v036/types.go @@ -1,5 +1,5 @@ // DONTCOVER -// nolint + package v036 import ( diff --git a/x/distribution/legacy/v038/migrate.go b/x/distribution/legacy/v038/migrate.go index cd00668b1efd..73e933da4589 100644 --- a/x/distribution/legacy/v038/migrate.go +++ b/x/distribution/legacy/v038/migrate.go @@ -1,7 +1,6 @@ package v038 // DONTCOVER -// nolint import ( v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036" diff --git a/x/distribution/legacy/v038/types.go b/x/distribution/legacy/v038/types.go index af7146418dbc..335fbc1245e2 100644 --- a/x/distribution/legacy/v038/types.go +++ b/x/distribution/legacy/v038/types.go @@ -7,7 +7,6 @@ import ( ) // DONTCOVER -// nolint const ( ModuleName = "distribution" diff --git a/x/distribution/module.go b/x/distribution/module.go index 034be6d9651d..339fdfde55e0 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -88,7 +88,7 @@ func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the distribution module. type AppModule struct { @@ -172,7 +172,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/evidence/module.go b/x/evidence/module.go index 4367fe8d58ce..991ab271b0a5 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -186,7 +186,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/genaccounts/legacy/v034/types.go b/x/genaccounts/legacy/v034/types.go index 080b534d8ec1..f4bb73fa37c4 100644 --- a/x/genaccounts/legacy/v034/types.go +++ b/x/genaccounts/legacy/v034/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v034 import ( diff --git a/x/genaccounts/legacy/v036/types.go b/x/genaccounts/legacy/v036/types.go index 8d143e69d2dc..e91db341db48 100644 --- a/x/genaccounts/legacy/v036/types.go +++ b/x/genaccounts/legacy/v036/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/genutil/client/cli/init.go b/x/genutil/client/cli/init.go index 074bb7da4e74..f5fda79c69f0 100644 --- a/x/genutil/client/cli/init.go +++ b/x/genutil/client/cli/init.go @@ -89,11 +89,12 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { recover, _ := cmd.Flags().GetBool(FlagRecover) if recover { inBuf := bufio.NewReader(cmd.InOrStdin()) - mnemonic, err := input.GetString("Enter your bip39 mnemonic", inBuf) + value, err := input.GetString("Enter your bip39 mnemonic", inBuf) if err != nil { return err } + mnemonic = value if !bip39.IsMnemonicValid(mnemonic) { return errors.New("invalid mnemonic") } diff --git a/x/genutil/module.go b/x/genutil/module.go index bfaeb0c59168..ba0d76a01a94 100644 --- a/x/genutil/module.go +++ b/x/genutil/module.go @@ -66,7 +66,7 @@ func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } // GetQueryCmd returns no root query command for the genutil module. func (AppModuleBasic) GetQueryCmd() *cobra.Command { return nil } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the genutil module. type AppModule struct { diff --git a/x/gov/client/cli/query.go b/x/gov/client/cli/query.go index 8c67cd96e5e1..1b7f7995f42e 100644 --- a/x/gov/client/cli/query.go +++ b/x/gov/client/cli/query.go @@ -364,8 +364,9 @@ $ %s query gov deposit 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk } // check to see if the proposal is in the store - _, err = queryClient.Proposal( - context.Background(), + ctx := cmd.Context() + proposalRes, err := queryClient.Proposal( + ctx, &types.QueryProposalRequest{ProposalId: proposalID}, ) if err != nil { @@ -377,25 +378,27 @@ $ %s query gov deposit 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk return err } - res, err := queryClient.Deposit( - context.Background(), - &types.QueryDepositRequest{ProposalId: proposalID, Depositor: args[1]}, - ) - if err != nil { - return err - } - - deposit := res.GetDeposit() - if deposit.Empty() { + var deposit types.Deposit + propStatus := proposalRes.Proposal.Status + if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { params := types.NewQueryDepositParams(proposalID, depositorAddr) resByTxQuery, err := gcutils.QueryDepositByTxQuery(clientCtx, params) if err != nil { return err } clientCtx.JSONMarshaler.MustUnmarshalJSON(resByTxQuery, &deposit) + return clientCtx.PrintProto(&deposit) + } + + res, err := queryClient.Deposit( + ctx, + &types.QueryDepositRequest{ProposalId: proposalID, Depositor: args[1]}, + ) + if err != nil { + return err } - return clientCtx.PrintProto(&deposit) + return clientCtx.PrintProto(&res.Deposit) }, } diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index f11798e96760..46d66c240bc2 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -12,7 +12,6 @@ import ( ) // REST Variable names -// nolint const ( RestParamsType = "type" RestProposalID = "proposal-id" diff --git a/x/gov/client/testutil/cli_test.go b/x/gov/client/testutil/cli_test.go new file mode 100644 index 000000000000..e28ba13dcd2d --- /dev/null +++ b/x/gov/client/testutil/cli_test.go @@ -0,0 +1,27 @@ +// +build norace + +package testutil + +import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +func TestIntegrationTestSuite(t *testing.T) { + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + genesisState := types.DefaultGenesisState() + genesisState.DepositParams = types.NewDepositParams(sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, types.DefaultMinDepositTokens)), time.Duration(15)*time.Second) + genesisState.VotingParams = types.NewVotingParams(time.Duration(5) * time.Second) + bz, err := cfg.Codec.MarshalJSON(genesisState) + require.NoError(t, err) + cfg.GenesisState["gov"] = bz + suite.Run(t, NewDepositTestSuite(cfg)) +} diff --git a/x/gov/client/testutil/deposits.go b/x/gov/client/testutil/deposits.go new file mode 100644 index 000000000000..57c3c9363330 --- /dev/null +++ b/x/gov/client/testutil/deposits.go @@ -0,0 +1,193 @@ +package testutil + +import ( + "fmt" + "time" + + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/stretchr/testify/suite" + tmcli "github.com/tendermint/tendermint/libs/cli" +) + +type DepositTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network + fees string +} + +func NewDepositTestSuite(cfg network.Config) *DepositTestSuite { + return &DepositTestSuite{cfg: cfg} +} + +func (s *DepositTestSuite) SetupSuite() { + s.T().Log("setting up test suite") + + s.network = network.New(s.T(), s.cfg) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) + s.fees = sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String() + +} + +func (s *DepositTestSuite) TearDownSuite() { + s.T().Log("tearing down test suite") + s.network.Cleanup() +} + +func (s *DepositTestSuite) TestQueryDepositsInitialDeposit() { + val := s.network.Validators[0] + clientCtx := val.ClientCtx + initialDeposit := sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens.Sub(sdk.NewInt(20))).String() + + // create a proposal with deposit + _, err := MsgSubmitProposal(val.ClientCtx, val.Address.String(), + "Text Proposal 1", "Where is the title!?", types.ProposalTypeText, + fmt.Sprintf("--%s=%s", cli.FlagDeposit, initialDeposit)) + s.Require().NoError(err) + + // deposit more amount + _, err = MsgDeposit(clientCtx, val.Address.String(), "1", sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(50)).String()) + s.Require().NoError(err) + + // waiting for voting period to end + time.Sleep(20 * time.Second) + + // query deposit & verify initial deposit + deposit := s.queryDeposit(val, "1", false) + s.Require().Equal(deposit.Amount.String(), initialDeposit) + + // query deposits + deposits := s.queryDeposits(val, "1", false) + s.Require().Equal(len(deposits), 2) + // verify initial deposit + s.Require().Equal(deposits[0].Amount.String(), initialDeposit) +} + +func (s *DepositTestSuite) TestQueryDepositsWithoutInitialDeposit() { + val := s.network.Validators[0] + clientCtx := val.ClientCtx + + // create a proposal without deposit + _, err := MsgSubmitProposal(val.ClientCtx, val.Address.String(), + "Text Proposal 2", "Where is the title!?", types.ProposalTypeText) + s.Require().NoError(err) + + // deposit amount + _, err = MsgDeposit(clientCtx, val.Address.String(), "2", sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens.Add(sdk.NewInt(50))).String()) + s.Require().NoError(err) + + // waiting for voting period to end + time.Sleep(20 * time.Second) + + // query deposit + deposit := s.queryDeposit(val, "2", false) + s.Require().Equal(deposit.Amount.String(), sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens.Add(sdk.NewInt(50))).String()) + + // query deposits + deposits := s.queryDeposits(val, "2", false) + s.Require().Equal(len(deposits), 1) + // verify initial deposit + s.Require().Equal(deposits[0].Amount.String(), sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens.Add(sdk.NewInt(50))).String()) +} + +func (s *DepositTestSuite) TestQueryProposalNotEnoughDeposits() { + val := s.network.Validators[0] + clientCtx := val.ClientCtx + initialDeposit := sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens.Sub(sdk.NewInt(2000))).String() + + // create a proposal with deposit + _, err := MsgSubmitProposal(val.ClientCtx, val.Address.String(), + "Text Proposal 3", "Where is the title!?", types.ProposalTypeText, + fmt.Sprintf("--%s=%s", cli.FlagDeposit, initialDeposit)) + s.Require().NoError(err) + + // query proposal + args := []string{"3", fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + cmd := cli.GetCmdQueryProposal() + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + s.Require().NoError(err) + + // waiting for deposit period to end + time.Sleep(20 * time.Second) + + // query proposal + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + s.Require().Error(err) + s.Require().Contains(err.Error(), "proposal 3 doesn't exist") +} + +func (s *DepositTestSuite) TestRejectedProposalDeposits() { + val := s.network.Validators[0] + clientCtx := val.ClientCtx + initialDeposit := sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens) + + // create a proposal with deposit + _, err := MsgSubmitProposal(clientCtx, val.Address.String(), + "Text Proposal 4", "Where is the title!?", types.ProposalTypeText, + fmt.Sprintf("--%s=%s", cli.FlagDeposit, initialDeposit)) + s.Require().NoError(err) + + // query deposits + var deposits types.QueryDepositsResponse + args := []string{"4", fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + cmd := cli.GetCmdQueryDeposits() + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(out.Bytes(), &deposits)) + s.Require().Equal(len(deposits.Deposits), 1) + // verify initial deposit + s.Require().Equal(deposits.Deposits[0].Amount.String(), sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens).String()) + + // vote + _, err = MsgVote(clientCtx, val.Address.String(), "4", "no") + s.Require().NoError(err) + + time.Sleep(20 * time.Second) + + args = []string{"4", fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + cmd = cli.GetCmdQueryProposal() + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + s.Require().NoError(err) + + // query deposits + depositsRes := s.queryDeposits(val, "4", false) + s.Require().Equal(len(depositsRes), 1) + // verify initial deposit + s.Require().Equal(depositsRes[0].Amount.String(), initialDeposit.String()) + +} + +func (s *DepositTestSuite) queryDeposits(val *network.Validator, proposalID string, exceptErr bool) types.Deposits { + args := []string{proposalID, fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + var depositsRes types.Deposits + cmd := cli.GetCmdQueryDeposits() + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) + if exceptErr { + s.Require().Error(err) + return nil + } + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(out.Bytes(), &depositsRes)) + return depositsRes +} + +func (s *DepositTestSuite) queryDeposit(val *network.Validator, proposalID string, exceptErr bool) *types.Deposit { + args := []string{proposalID, val.Address.String(), fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + var depositRes types.Deposit + cmd := cli.GetCmdQueryDeposit() + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) + if exceptErr { + s.Require().Error(err) + return nil + } + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(out.Bytes(), &depositRes)) + return &depositRes +} diff --git a/x/gov/client/testutil/helpers.go b/x/gov/client/testutil/helpers.go index 535cb8d09ca6..36fdabbbcd2f 100644 --- a/x/gov/client/testutil/helpers.go +++ b/x/gov/client/testutil/helpers.go @@ -43,3 +43,15 @@ func MsgVote(clientCtx client.Context, from, id, vote string, extraArgs ...strin return clitestutil.ExecTestCLICmd(clientCtx, govcli.NewCmdVote(), args) } + +func MsgDeposit(clientCtx client.Context, from, id, deposit string, extraArgs ...string) (testutil.BufferWriter, error) { + args := append([]string{ + id, + deposit, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + }, commonArgs...) + + args = append(args, extraArgs...) + + return clitestutil.ExecTestCLICmd(clientCtx, govcli.NewCmdDeposit(), args) +} diff --git a/x/gov/client/utils/query.go b/x/gov/client/utils/query.go index e543f526b3f0..c3c590da30fe 100644 --- a/x/gov/client/utils/query.go +++ b/x/gov/client/utils/query.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -37,6 +38,18 @@ func (p Proposer) String() string { // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. func QueryDepositsByTxQuery(clientCtx client.Context, params types.QueryProposalParams) ([]byte, error) { + var deposits []types.Deposit + + // initial deposit was submitted with proposal, so must be queried separately + initialDeposit, err := queryInitialDepositByTxQuery(clientCtx, params.ProposalID) + if err != nil { + return nil, err + } + + if !initialDeposit.Amount.IsZero() { + deposits = append(deposits, initialDeposit) + } + events := []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), @@ -49,8 +62,6 @@ func QueryDepositsByTxQuery(clientCtx client.Context, params types.QueryProposal return nil, err } - var deposits []types.Deposit - for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { if msg.Type() == types.TypeMsgDeposit { @@ -167,6 +178,21 @@ func QueryVoteByTxQuery(clientCtx client.Context, params types.QueryVoteParams) // QueryDepositByTxQuery will query for a single deposit via a direct txs tags // query. func QueryDepositByTxQuery(clientCtx client.Context, params types.QueryDepositParams) ([]byte, error) { + // initial deposit was submitted with proposal, so must be queried separately + initialDeposit, err := queryInitialDepositByTxQuery(clientCtx, params.ProposalID) + if err != nil { + return nil, err + } + + if !initialDeposit.Amount.IsZero() { + bz, err := clientCtx.JSONMarshaler.MarshalJSON(&initialDeposit) + if err != nil { + return nil, err + } + + return bz, nil + } + events := []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), @@ -248,3 +274,33 @@ func QueryProposalByID(proposalID uint64, clientCtx client.Context, queryRoute s return res, err } + +// queryInitialDepositByTxQuery will query for a initial deposit of a governance proposal by +// ID. +func queryInitialDepositByTxQuery(clientCtx client.Context, proposalID uint64) (types.Deposit, error) { + // Query legacy Msgs event action + events := []string{ + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgSubmitProposal), + fmt.Sprintf("%s.%s='%s'", types.EventTypeSubmitProposal, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))), + } + searchResult, err := authclient.QueryTxsByEvents(clientCtx, events, defaultPage, defaultLimit, "") + + if err != nil { + return types.Deposit{}, err + } + + for _, info := range searchResult.Txs { + for _, msg := range info.GetTx().GetMsgs() { + // there should only be a single proposal under the given conditions + if subMsg, ok := msg.(*types.MsgSubmitProposal); ok { + return types.Deposit{ + ProposalId: proposalID, + Depositor: subMsg.Proposer, + Amount: subMsg.InitialDeposit, + }, nil + } + } + } + + return types.Deposit{}, sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "failed to find the initial deposit for proposalID %d", proposalID) +} diff --git a/x/gov/client/utils/utils.go b/x/gov/client/utils/utils.go index 86e4dc5f3e96..2562dab08cfe 100644 --- a/x/gov/client/utils/utils.go +++ b/x/gov/client/utils/utils.go @@ -22,7 +22,7 @@ func NormalizeVoteOption(option string) string { } } -//NormalizeProposalType - normalize user specified proposal type +// NormalizeProposalType - normalize user specified proposal type func NormalizeProposalType(proposalType string) string { switch proposalType { case "Text", "text": @@ -33,7 +33,7 @@ func NormalizeProposalType(proposalType string) string { } } -//NormalizeProposalStatus - normalize user specified proposal status +// NormalizeProposalStatus - normalize user specified proposal status func NormalizeProposalStatus(status string) string { switch status { case "DepositPeriod", "deposit_period": diff --git a/x/gov/legacy/v034/types.go b/x/gov/legacy/v034/types.go index dd98cca21be3..14e0b7a26590 100644 --- a/x/gov/legacy/v034/types.go +++ b/x/gov/legacy/v034/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v034 import ( diff --git a/x/gov/legacy/v036/types.go b/x/gov/legacy/v036/types.go index d0bc4620bc73..6632c6da255c 100644 --- a/x/gov/legacy/v036/types.go +++ b/x/gov/legacy/v036/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/gov/module.go b/x/gov/module.go index ad2191660c08..b2eb38c1d33e 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -109,7 +109,7 @@ func (a AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the gov module. type AppModule struct { @@ -187,7 +187,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/ibc/applications/transfer/client/cli/cli.go b/x/ibc/applications/transfer/client/cli/cli.go index d3ca8341e95c..643af5041787 100644 --- a/x/ibc/applications/transfer/client/cli/cli.go +++ b/x/ibc/applications/transfer/client/cli/cli.go @@ -19,6 +19,7 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryDenomTrace(), GetCmdQueryDenomTraces(), GetCmdParams(), + GetCmdQueryEscrowAddress(), ) return queryCmd diff --git a/x/ibc/applications/transfer/client/cli/query.go b/x/ibc/applications/transfer/client/cli/query.go index 7d281bb4155f..b9ac7263175c 100644 --- a/x/ibc/applications/transfer/client/cli/query.go +++ b/x/ibc/applications/transfer/client/cli/query.go @@ -107,3 +107,25 @@ func GetCmdParams() *cobra.Command { return cmd } + +// GetCmdParams returns the command handler for ibc-transfer parameter querying. +func GetCmdQueryEscrowAddress() *cobra.Command { + cmd := &cobra.Command{ + Use: "escrow-address", + Short: "Get the escrow address for a channel", + Long: "Get the escrow address for a channel", + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query ibc-transfer escrow-address [port] [channel-id]", version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + port := args[0] + channel := args[1] + addr := types.GetEscrowAddress(port, channel) + fmt.Println(addr.String()) + return nil + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ibc/applications/transfer/keeper/relay.go b/x/ibc/applications/transfer/keeper/relay.go index 4889014a40af..cbe4a0749b0f 100644 --- a/x/ibc/applications/transfer/keeper/relay.go +++ b/x/ibc/applications/transfer/keeper/relay.go @@ -13,6 +13,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" + coretypes "github.com/cosmos/cosmos-sdk/x/ibc/core/types" ) // SendTransfer handles transfer sending logic. There are 2 possible cases: @@ -101,8 +102,8 @@ func (k Keeper) SendTransfer( } labels := []metrics.Label{ - telemetry.NewLabel("destination-port", destinationPort), - telemetry.NewLabel("destination-channel", destinationChannel), + telemetry.NewLabel(coretypes.LabelDestinationPort, destinationPort), + telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel), } // NOTE: SendTransfer simply sends the denomination as it exists on its own @@ -110,7 +111,7 @@ func (k Keeper) SendTransfer( // prefixing as necessary. if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) { - labels = append(labels, telemetry.NewLabel("source", "true")) + labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "true")) // create the escrow address for the tokens escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) @@ -123,7 +124,7 @@ func (k Keeper) SendTransfer( } } else { - labels = append(labels, telemetry.NewLabel("source", "false")) + labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false")) // transfer the coins to the module account and burn them if err := k.bankKeeper.SendCoinsFromAccountToModule( @@ -165,7 +166,7 @@ func (k Keeper) SendTransfer( telemetry.SetGaugeWithLabels( []string{"tx", "msg", "ibc", "transfer"}, float32(token.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", fullDenomPath)}, + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, fullDenomPath)}, ) telemetry.IncrCounterWithLabels( @@ -200,8 +201,8 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t } labels := []metrics.Label{ - telemetry.NewLabel("source-port", packet.GetSourcePort()), - telemetry.NewLabel("source-channel", packet.GetSourceChannel()), + telemetry.NewLabel(coretypes.LabelSourcePort, packet.GetSourcePort()), + telemetry.NewLabel(coretypes.LabelSourceChannel, packet.GetSourceChannel()), } // This is the prefix that would have been prefixed to the denomination @@ -244,14 +245,14 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t telemetry.SetGaugeWithLabels( []string{"ibc", types.ModuleName, "packet", "receive"}, float32(data.Amount), - []metrics.Label{telemetry.NewLabel("denom", unprefixedDenom)}, + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, unprefixedDenom)}, ) telemetry.IncrCounterWithLabels( []string{"ibc", types.ModuleName, "receive"}, 1, append( - labels, telemetry.NewLabel("source", "true"), + labels, telemetry.NewLabel(coretypes.LabelSource, "true"), ), ) }() @@ -303,14 +304,14 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t telemetry.SetGaugeWithLabels( []string{"ibc", types.ModuleName, "packet", "receive"}, float32(data.Amount), - []metrics.Label{telemetry.NewLabel("denom", data.Denom)}, + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, data.Denom)}, ) telemetry.IncrCounterWithLabels( []string{"ibc", types.ModuleName, "receive"}, 1, append( - labels, telemetry.NewLabel("source", "false"), + labels, telemetry.NewLabel(coretypes.LabelSource, "false"), ), ) }() diff --git a/x/ibc/applications/transfer/module.go b/x/ibc/applications/transfer/module.go index 764f61e92bba..79de4e77b4cf 100644 --- a/x/ibc/applications/transfer/module.go +++ b/x/ibc/applications/transfer/module.go @@ -154,7 +154,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions @@ -183,7 +183,7 @@ func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.Weig return nil } -//____________________________________________________________________________ +// ____________________________________________________________________________ // ValidateTransferChannelParams does validation of a newly created transfer channel. A transfer // channel must be UNORDERED, use the correct port (by default 'transfer'), and use the current @@ -343,7 +343,7 @@ func (am AppModule) OnRecvPacket( sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), sdk.NewAttribute(types.AttributeKeyAmount, fmt.Sprintf("%d", data.Amount)), - sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", err != nil)), + sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", err == nil)), ), ) diff --git a/x/ibc/applications/transfer/simulation/params.go b/x/ibc/applications/transfer/simulation/params.go index 67c61f514ed1..0f4fefb93b43 100644 --- a/x/ibc/applications/transfer/simulation/params.go +++ b/x/ibc/applications/transfer/simulation/params.go @@ -1,7 +1,6 @@ package simulation import ( - "fmt" "math/rand" gogotypes "github.com/gogo/protobuf/types" @@ -19,13 +18,13 @@ func ParamChanges(r *rand.Rand) []simtypes.ParamChange { simulation.NewSimParamChange(types.ModuleName, string(types.KeySendEnabled), func(r *rand.Rand) string { sendEnabled := RadomEnabled(r) - return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: sendEnabled})) + return string(types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: sendEnabled})) }, ), simulation.NewSimParamChange(types.ModuleName, string(types.KeyReceiveEnabled), func(r *rand.Rand) string { receiveEnabled := RadomEnabled(r) - return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: receiveEnabled})) + return string(types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: receiveEnabled})) }, ), } diff --git a/x/ibc/core/02-client/client/utils/utils.go b/x/ibc/core/02-client/client/utils/utils.go index 1a7bc003bc51..847abb00d250 100644 --- a/x/ibc/core/02-client/client/utils/utils.go +++ b/x/ibc/core/02-client/client/utils/utils.go @@ -131,14 +131,19 @@ func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, return ibctmtypes.Header{}, 0, err } - height := info.Response.LastBlockHeight + var height int64 + if clientCtx.Height != 0 { + height = clientCtx.Height + } else { + height = info.Response.LastBlockHeight + } commit, err := node.Commit(context.Background(), &height) if err != nil { return ibctmtypes.Header{}, 0, err } - page := 0 + page := 1 count := 10_000 validators, err := node.Validators(context.Background(), &height, &page, &count) @@ -173,7 +178,12 @@ func QueryNodeConsensusState(clientCtx client.Context) (*ibctmtypes.ConsensusSta return &ibctmtypes.ConsensusState{}, 0, err } - height := info.Response.LastBlockHeight + var height int64 + if clientCtx.Height != 0 { + height = clientCtx.Height + } else { + height = info.Response.LastBlockHeight + } commit, err := node.Commit(context.Background(), &height) if err != nil { diff --git a/x/ibc/core/02-client/genesis.go b/x/ibc/core/02-client/genesis.go index 26635f0784c8..659d697e00e5 100644 --- a/x/ibc/core/02-client/genesis.go +++ b/x/ibc/core/02-client/genesis.go @@ -60,10 +60,11 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { panic(err) } return types.GenesisState{ - Clients: genClients, - ClientsMetadata: clientsMetadata, - ClientsConsensus: k.GetAllConsensusStates(ctx), - Params: k.GetParams(ctx), - CreateLocalhost: false, + Clients: genClients, + ClientsMetadata: clientsMetadata, + ClientsConsensus: k.GetAllConsensusStates(ctx), + Params: k.GetParams(ctx), + CreateLocalhost: false, + NextClientSequence: k.GetNextClientSequence(ctx), } } diff --git a/x/ibc/core/02-client/keeper/client.go b/x/ibc/core/02-client/keeper/client.go index e822402bfb3e..b4ca97f81bcd 100644 --- a/x/ibc/core/02-client/keeper/client.go +++ b/x/ibc/core/02-client/keeper/client.go @@ -47,7 +47,7 @@ func (k Keeper) CreateClient( telemetry.IncrCounterWithLabels( []string{"ibc", "client", "create"}, 1, - []metrics.Label{telemetry.NewLabel("client-type", clientState.ClientType())}, + []metrics.Label{telemetry.NewLabel(types.LabelClientType, clientState.ClientType())}, ) }() @@ -90,9 +90,9 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H []string{"ibc", "client", "update"}, 1, []metrics.Label{ - telemetry.NewLabel("client-type", clientState.ClientType()), - telemetry.NewLabel("client-id", clientID), - telemetry.NewLabel("update-type", "msg"), + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + telemetry.NewLabel(types.LabelUpdateType, "msg"), }, ) }() @@ -151,8 +151,8 @@ func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient e []string{"ibc", "client", "upgrade"}, 1, []metrics.Label{ - telemetry.NewLabel("client-type", updatedClientState.ClientType()), - telemetry.NewLabel("client-id", clientID), + telemetry.NewLabel(types.LabelClientType, updatedClientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), }, ) }() @@ -195,8 +195,8 @@ func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour ex []string{"ibc", "client", "misbehaviour"}, 1, []metrics.Label{ - telemetry.NewLabel("client-type", misbehaviour.ClientType()), - telemetry.NewLabel("client-id", misbehaviour.GetClientID()), + telemetry.NewLabel(types.LabelClientType, misbehaviour.ClientType()), + telemetry.NewLabel(types.LabelClientID, misbehaviour.GetClientID()), }, ) }() diff --git a/x/ibc/core/02-client/keeper/client_test.go b/x/ibc/core/02-client/keeper/client_test.go index 21d59b74025c..0f14ef2135bf 100644 --- a/x/ibc/core/02-client/keeper/client_test.go +++ b/x/ibc/core/02-client/keeper/client_test.go @@ -615,8 +615,8 @@ func (suite *KeeperTestSuite) TestUpdateClientEventEmission() { result, err := suite.chainA.SendMsgs(msg) suite.Require().NoError(err) - // first event type is "message" - updateEvent := result.Events[1] + // first 3 event type are "tx.signature", "tx.acc_seq", and "message" + updateEvent := result.Events[3] suite.Require().Equal(clienttypes.EventTypeUpdateClient, updateEvent.Type) diff --git a/x/ibc/core/02-client/keeper/proposal.go b/x/ibc/core/02-client/keeper/proposal.go index 6b17278e09dd..17244562aed8 100644 --- a/x/ibc/core/02-client/keeper/proposal.go +++ b/x/ibc/core/02-client/keeper/proposal.go @@ -42,9 +42,9 @@ func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdatePropo []string{"ibc", "client", "update"}, 1, []metrics.Label{ - telemetry.NewLabel("client-type", clientState.ClientType()), - telemetry.NewLabel("client-id", p.ClientId), - telemetry.NewLabel("update-type", "proposal"), + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, p.ClientId), + telemetry.NewLabel(types.LabelUpdateType, "proposal"), }, ) }() diff --git a/x/ibc/core/02-client/types/metrics.go b/x/ibc/core/02-client/types/metrics.go new file mode 100644 index 000000000000..879e79a40d13 --- /dev/null +++ b/x/ibc/core/02-client/types/metrics.go @@ -0,0 +1,9 @@ +package types + +// Prometheus metric labels. +const ( + LabelClientType = "client_type" + LabelClientID = "client_id" + LabelUpdateType = "update_type" + LabelMsgType = "msg_type" +) diff --git a/x/ibc/core/03-connection/genesis.go b/x/ibc/core/03-connection/genesis.go index a1bb30f1fe56..12059aff10e2 100644 --- a/x/ibc/core/03-connection/genesis.go +++ b/x/ibc/core/03-connection/genesis.go @@ -22,7 +22,8 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { // ExportGenesis returns the ibc connection submodule's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { return types.GenesisState{ - Connections: k.GetAllConnections(ctx), - ClientConnectionPaths: k.GetAllClientConnectionPaths(ctx), + Connections: k.GetAllConnections(ctx), + ClientConnectionPaths: k.GetAllClientConnectionPaths(ctx), + NextConnectionSequence: k.GetNextConnectionSequence(ctx), } } diff --git a/x/ibc/core/04-channel/genesis.go b/x/ibc/core/04-channel/genesis.go index 07fad47d77b2..ae6bcb1edeb1 100644 --- a/x/ibc/core/04-channel/genesis.go +++ b/x/ibc/core/04-channel/genesis.go @@ -37,12 +37,13 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { // ExportGenesis returns the ibc channel submodule's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { return types.GenesisState{ - Channels: k.GetAllChannels(ctx), - Acknowledgements: k.GetAllPacketAcks(ctx), - Commitments: k.GetAllPacketCommitments(ctx), - Receipts: k.GetAllPacketReceipts(ctx), - SendSequences: k.GetAllPacketSendSeqs(ctx), - RecvSequences: k.GetAllPacketRecvSeqs(ctx), - AckSequences: k.GetAllPacketAckSeqs(ctx), + Channels: k.GetAllChannels(ctx), + Acknowledgements: k.GetAllPacketAcks(ctx), + Commitments: k.GetAllPacketCommitments(ctx), + Receipts: k.GetAllPacketReceipts(ctx), + SendSequences: k.GetAllPacketSendSeqs(ctx), + RecvSequences: k.GetAllPacketRecvSeqs(ctx), + AckSequences: k.GetAllPacketAckSeqs(ctx), + NextChannelSequence: k.GetNextChannelSequence(ctx), } } diff --git a/x/ibc/core/04-channel/types/errors.go b/x/ibc/core/04-channel/types/errors.go index 82cf773057d7..b1d11e1fddd5 100644 --- a/x/ibc/core/04-channel/types/errors.go +++ b/x/ibc/core/04-channel/types/errors.go @@ -25,4 +25,7 @@ var ( ErrPacketReceived = sdkerrors.Register(SubModuleName, 18, "packet already received") ErrAcknowledgementExists = sdkerrors.Register(SubModuleName, 19, "acknowledgement for packet already exists") ErrInvalidChannelIdentifier = sdkerrors.Register(SubModuleName, 20, "invalid channel identifier") + + // Antehandler error + ErrRedundantTx = sdkerrors.Register(SubModuleName, 22, "packet messages are redundant") ) diff --git a/x/ibc/core/ante/ante.go b/x/ibc/core/ante/ante.go new file mode 100644 index 000000000000..b3cae30245e5 --- /dev/null +++ b/x/ibc/core/ante/ante.go @@ -0,0 +1,72 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" + channelkeeper "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/keeper" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" +) + +type Decorator struct { + k channelkeeper.Keeper +} + +func NewAnteDecorator(k channelkeeper.Keeper) Decorator { + return Decorator{k: k} +} + +// AnteDecorator returns an error if a multiMsg tx only contains packet messages (Recv, Ack, Timeout) and additional update messages and all packet messages +// are redundant. If the transaction is just a single UpdateClient message, or the multimsg transaction contains some other message type, then the antedecorator returns no error +// and continues processing to ensure these transactions are included. +// This will ensure that relayers do not waste fees on multiMsg transactions when another relayer has already submitted all packets, by rejecting the tx at the mempool layer. +func (ad Decorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + // do not run redundancy check on DeliverTx or simulate + if (ctx.IsCheckTx() || ctx.IsReCheckTx()) && !simulate { + // keep track of total packet messages and number of redundancies across `RecvPacket`, `AcknowledgePacket`, and `TimeoutPacket/OnClose` + redundancies := 0 + packetMsgs := 0 + for _, m := range tx.GetMsgs() { + switch msg := m.(type) { + case *channeltypes.MsgRecvPacket: + if _, found := ad.k.GetPacketReceipt(ctx, msg.Packet.GetDestPort(), msg.Packet.GetDestChannel(), msg.Packet.GetSequence()); found { + redundancies++ + } + packetMsgs++ + + case *channeltypes.MsgAcknowledgement: + if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + redundancies++ + } + packetMsgs++ + + case *channeltypes.MsgTimeout: + if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + redundancies++ + } + packetMsgs++ + + case *channeltypes.MsgTimeoutOnClose: + if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + redundancies++ + } + packetMsgs++ + + case *clienttypes.MsgUpdateClient: + // do nothing here, as we want to avoid updating clients if it is batched with only redundant messages + + default: + // if the multiMsg tx has a msg that is not a packet msg or update msg, then we will not return error + // regardless of if all packet messages are redundant. This ensures that non-packet messages get processed + // even if they get batched with redundant packet messages. + return next(ctx, tx, simulate) + } + + } + + // only return error if all packet messages are redundant + if redundancies == packetMsgs && packetMsgs > 0 { + return ctx, channeltypes.ErrRedundantTx + } + } + return next(ctx, tx, simulate) +} diff --git a/x/ibc/core/keeper/msg_server.go b/x/ibc/core/keeper/msg_server.go index dcddcaed16d4..7a65b2a1fd77 100644 --- a/x/ibc/core/keeper/msg_server.go +++ b/x/ibc/core/keeper/msg_server.go @@ -13,6 +13,7 @@ import ( channel "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" porttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/05-port/types" + coretypes "github.com/cosmos/cosmos-sdk/x/ibc/core/types" ) var _ clienttypes.MsgServer = Keeper{} @@ -462,10 +463,10 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke []string{"tx", "msg", "ibc", msg.Type()}, 1, []metrics.Label{ - telemetry.NewLabel("source-port", msg.Packet.SourcePort), - telemetry.NewLabel("source-channel", msg.Packet.SourceChannel), - telemetry.NewLabel("destination-port", msg.Packet.DestinationPort), - telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel), + telemetry.NewLabel(coretypes.LabelSourcePort, msg.Packet.SourcePort), + telemetry.NewLabel(coretypes.LabelSourceChannel, msg.Packet.SourceChannel), + telemetry.NewLabel(coretypes.LabelDestinationPort, msg.Packet.DestinationPort), + telemetry.NewLabel(coretypes.LabelDestinationChannel, msg.Packet.DestinationChannel), }, ) }() @@ -509,11 +510,11 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c []string{"ibc", "timeout", "packet"}, 1, []metrics.Label{ - telemetry.NewLabel("source-port", msg.Packet.SourcePort), - telemetry.NewLabel("source-channel", msg.Packet.SourceChannel), - telemetry.NewLabel("destination-port", msg.Packet.DestinationPort), - telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel), - telemetry.NewLabel("timeout-type", "height"), + telemetry.NewLabel(coretypes.LabelSourcePort, msg.Packet.SourcePort), + telemetry.NewLabel(coretypes.LabelSourceChannel, msg.Packet.SourceChannel), + telemetry.NewLabel(coretypes.LabelDestinationPort, msg.Packet.DestinationPort), + telemetry.NewLabel(coretypes.LabelDestinationChannel, msg.Packet.DestinationChannel), + telemetry.NewLabel(coretypes.LabelTimeoutType, "height"), }, ) }() @@ -560,11 +561,11 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo []string{"ibc", "timeout", "packet"}, 1, []metrics.Label{ - telemetry.NewLabel("source-port", msg.Packet.SourcePort), - telemetry.NewLabel("source-channel", msg.Packet.SourceChannel), - telemetry.NewLabel("destination-port", msg.Packet.DestinationPort), - telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel), - telemetry.NewLabel("timeout-type", "channel-closed"), + telemetry.NewLabel(coretypes.LabelSourcePort, msg.Packet.SourcePort), + telemetry.NewLabel(coretypes.LabelSourceChannel, msg.Packet.SourceChannel), + telemetry.NewLabel(coretypes.LabelDestinationPort, msg.Packet.DestinationPort), + telemetry.NewLabel(coretypes.LabelDestinationChannel, msg.Packet.DestinationChannel), + telemetry.NewLabel(coretypes.LabelTimeoutType, "channel-closed"), }, ) }() @@ -604,10 +605,10 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn []string{"tx", "msg", "ibc", msg.Type()}, 1, []metrics.Label{ - telemetry.NewLabel("source-port", msg.Packet.SourcePort), - telemetry.NewLabel("source-channel", msg.Packet.SourceChannel), - telemetry.NewLabel("destination-port", msg.Packet.DestinationPort), - telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel), + telemetry.NewLabel(coretypes.LabelSourcePort, msg.Packet.SourcePort), + telemetry.NewLabel(coretypes.LabelSourceChannel, msg.Packet.SourceChannel), + telemetry.NewLabel(coretypes.LabelDestinationPort, msg.Packet.DestinationPort), + telemetry.NewLabel(coretypes.LabelDestinationChannel, msg.Packet.DestinationChannel), }, ) }() diff --git a/x/ibc/core/module.go b/x/ibc/core/module.go index 3371dc88a446..506bb1338973 100644 --- a/x/ibc/core/module.go +++ b/x/ibc/core/module.go @@ -167,7 +167,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/ibc/core/types/metrics.go b/x/ibc/core/types/metrics.go new file mode 100644 index 000000000000..9fcd348a7d6e --- /dev/null +++ b/x/ibc/core/types/metrics.go @@ -0,0 +1,12 @@ +package types + +// Prometheus metric labels. +const ( + LabelSourcePort = "source_port" + LabelSourceChannel = "source_channel" + LabelDestinationPort = "destination_port" + LabelDestinationChannel = "destination_channel" + LabelTimeoutType = "timeout_type" + LabelDenom = "denom" + LabelSource = "source" +) diff --git a/x/ibc/testing/mock/mock.go b/x/ibc/testing/mock/mock.go index 663497aa05ca..00df78230169 100644 --- a/x/ibc/testing/mock/mock.go +++ b/x/ibc/testing/mock/mock.go @@ -124,7 +124,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // OnChanOpenInit implements the IBCModule interface. func (am AppModule) OnChanOpenInit( diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index de0a31222845..2f002b01abce 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -45,7 +45,7 @@ func NewKeeper( } } -//______________________________________________________________________ +// ______________________________________________________________________ // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { @@ -71,7 +71,7 @@ func (k Keeper) SetMinter(ctx sdk.Context, minter types.Minter) { store.Set(types.MinterKey, b) } -//______________________________________________________________________ +// ______________________________________________________________________ // GetParams returns the total set of minting parameters. func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { @@ -84,7 +84,7 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { k.paramSpace.SetParamSet(ctx, ¶ms) } -//______________________________________________________________________ +// ______________________________________________________________________ // StakingTokenSupply implements an alias call to the underlying staking keeper's // StakingTokenSupply to be used in BeginBlocker. diff --git a/x/mint/module.go b/x/mint/module.go index 44e96ce74bda..6cef957040ec 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -83,7 +83,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { return cli.GetQueryCmd() } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the mint module. type AppModule struct { @@ -157,7 +157,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/params/module.go b/x/params/module.go index b0a4584129ef..d7aaabf9ddca 100644 --- a/x/params/module.go +++ b/x/params/module.go @@ -72,7 +72,7 @@ func (am AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistr proposal.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the distribution module. type AppModule struct { diff --git a/x/simulation/log.go b/x/simulation/log.go index 236a7244074f..b50163b33c33 100644 --- a/x/simulation/log.go +++ b/x/simulation/log.go @@ -68,7 +68,7 @@ func createLogFile() *os.File { return f } -//_____________________ +// _____________________ // dummy log writter type DummyLogWriter struct{} diff --git a/x/simulation/mock_tendermint.go b/x/simulation/mock_tendermint.go index ad84e8213d54..aea7cb2cf7a7 100644 --- a/x/simulation/mock_tendermint.go +++ b/x/simulation/mock_tendermint.go @@ -59,7 +59,7 @@ func (vals mockValidators) getKeys() []string { return keys } -//_________________________________________________________________________________ +// _________________________________________________________________________________ // randomProposer picks a random proposer from the current validator set func (vals mockValidators) randomProposer(r *rand.Rand) tmbytes.HexBytes { diff --git a/x/simulation/operation.go b/x/simulation/operation.go index 914daafc8b91..be396368435c 100644 --- a/x/simulation/operation.go +++ b/x/simulation/operation.go @@ -64,7 +64,7 @@ func (oe OperationEntry) MustMarshal() json.RawMessage { return out } -//_____________________________________________________________________ +// _____________________________________________________________________ // OperationQueue defines an object for a queue of operations type OperationQueue map[int][]simulation.Operation @@ -107,7 +107,7 @@ func queueOperations(queuedOps OperationQueue, queuedTimeOps []simulation.Future } } -//________________________________________________________________________ +// ________________________________________________________________________ // WeightedOperation is an operation with associated weight. // This is used to bias the selection operation within the simulator. diff --git a/x/simulation/simulate.go b/x/simulation/simulate.go index fdcf224611ba..a60f6b7feaa2 100644 --- a/x/simulation/simulate.go +++ b/x/simulation/simulate.go @@ -240,7 +240,7 @@ func SimulateFromSeed( return false, exportedParams, nil } -//______________________________________________________________________________ +// ______________________________________________________________________________ type blockSimFn func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simulation.Account, header tmproto.Header) (opCount int) diff --git a/x/slashing/keeper/hooks.go b/x/slashing/keeper/hooks.go index d59601425842..4a99b10e9f93 100644 --- a/x/slashing/keeper/hooks.go +++ b/x/slashing/keeper/hooks.go @@ -42,7 +42,7 @@ func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress) k.deleteAddrPubkeyRelation(ctx, crypto.Address(address)) } -//_________________________________________________________________________________________ +// _________________________________________________________________________________________ // Hooks wrapper struct for slashing keeper type Hooks struct { diff --git a/x/slashing/module.go b/x/slashing/module.go index 91ad472e90df..de773738a206 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -91,7 +91,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { return cli.GetQueryCmd() } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModule implements an application module for the slashing module. type AppModule struct { @@ -170,7 +170,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/slashing/simulation/operations.go b/x/slashing/simulation/operations.go index 20acc9e91a88..753def5fa5c3 100644 --- a/x/slashing/simulation/operations.go +++ b/x/slashing/simulation/operations.go @@ -43,7 +43,6 @@ func WeightedOperations( } // SimulateMsgUnjail generates a MsgUnjail with random values -// nolint: interfacer func SimulateMsgUnjail(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, sk stakingkeeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, diff --git a/x/slashing/types/events.go b/x/slashing/types/events.go index 62b6493c34a1..2e7eca79e950 100644 --- a/x/slashing/types/events.go +++ b/x/slashing/types/events.go @@ -1,4 +1,4 @@ -//noalias +// noalias package types // Slashing module event types diff --git a/x/staking/keeper/alias_functions.go b/x/staking/keeper/alias_functions.go index 1d563c690783..17ae5df2655c 100644 --- a/x/staking/keeper/alias_functions.go +++ b/x/staking/keeper/alias_functions.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -//_______________________________________________________________________ +// _______________________________________________________________________ // Validator Set // iterate through the validator set and perform the provided function @@ -96,7 +96,7 @@ func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) types return val } -//_______________________________________________________________________ +// _______________________________________________________________________ // Delegation Set // Returns self as it is both a validatorset and delegationset diff --git a/x/staking/keeper/querier.go b/x/staking/keeper/querier.go index 48272e245191..dc27ce6bb795 100644 --- a/x/staking/keeper/querier.go +++ b/x/staking/keeper/querier.go @@ -444,7 +444,7 @@ func queryParameters(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAm return res, nil } -//______________________________________________________ +// ______________________________________________________ // util func DelegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, error) { diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index a6f323092ae6..92dde56e514f 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -50,7 +50,7 @@ func (k Keeper) GetDelegatorValidator( return validator, nil } -//_____________________________________________________________________________________ +// _____________________________________________________________________________________ // return all delegations for a delegator func (k Keeper) GetAllDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress) []types.Delegation { @@ -59,7 +59,7 @@ func (k Keeper) GetAllDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAdd store := ctx.KVStore(k.storeKey) delegatorPrefixKey := types.GetDelegationsKey(delegator) - iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest defer iterator.Close() i := 0 diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 0760533ab9f0..03d0c90b2d70 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -384,7 +384,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { require.Equal(t, validator.GetStatus(), types.Unbonding) } -//_________________________________________________________________________________ +// _________________________________________________________________________________ // tests Slash at a previous height with a redelegation func TestSlashWithRedelegation(t *testing.T) { app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index 3aa1441767a4..0cc27098d87c 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -240,7 +240,7 @@ func (k Keeper) ValidatorsPowerStoreIterator(ctx sdk.Context) sdk.Iterator { return sdk.KVStoreReversePrefixIterator(store, types.ValidatorsByPowerIndexKey) } -//_______________________________________________________________________ +// _______________________________________________________________________ // Last Validator Index // Load the last validator power. diff --git a/x/staking/legacy/v034/types.go b/x/staking/legacy/v034/types.go index 9f8622d4bec2..539e6534bc5f 100644 --- a/x/staking/legacy/v034/types.go +++ b/x/staking/legacy/v034/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v034 import ( diff --git a/x/staking/legacy/v036/migrate.go b/x/staking/legacy/v036/migrate.go index cc4d7a4089b6..bb1f78bc4045 100644 --- a/x/staking/legacy/v036/migrate.go +++ b/x/staking/legacy/v036/migrate.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/staking/legacy/v036/types.go b/x/staking/legacy/v036/types.go index b433b0070100..44cf3746d153 100644 --- a/x/staking/legacy/v036/types.go +++ b/x/staking/legacy/v036/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v036 import ( diff --git a/x/staking/legacy/v038/migrate.go b/x/staking/legacy/v038/migrate.go index 21029881a3fd..d2f65edadfe7 100644 --- a/x/staking/legacy/v038/migrate.go +++ b/x/staking/legacy/v038/migrate.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v038 import ( diff --git a/x/staking/legacy/v038/types.go b/x/staking/legacy/v038/types.go index 58ffa1351ba5..e11157d0e473 100644 --- a/x/staking/legacy/v038/types.go +++ b/x/staking/legacy/v038/types.go @@ -1,5 +1,4 @@ // DONTCOVER -// nolint package v038 import ( diff --git a/x/staking/module.go b/x/staking/module.go index f2e422117476..48b5c6506527 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -168,7 +168,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val return EndBlocker(ctx, am.keeper) } -//____________________________________________________________________________ +// ____________________________________________________________________________ // AppModuleSimulation functions diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index 0bcb274ed717..11623509480a 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -92,7 +92,6 @@ func WeightedOperations( } // SimulateMsgCreateValidator generates a MsgCreateValidator with random values -// nolint: interfacer func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -178,7 +177,6 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k } // SimulateMsgEditValidator generates a MsgEditValidator with random values -// nolint: interfacer func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -249,7 +247,6 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k kee } // SimulateMsgDelegate generates a MsgDelegate with random values -// nolint: interfacer func SimulateMsgDelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -322,7 +319,6 @@ func SimulateMsgDelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.K } // SimulateMsgUndelegate generates a MsgUndelegate with random values -// nolint: interfacer func SimulateMsgUndelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -412,7 +408,6 @@ func SimulateMsgUndelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper } // SimulateMsgBeginRedelegate generates a MsgBeginRedelegate with random values -// nolint: interfacer func SimulateMsgBeginRedelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, diff --git a/x/staking/types/expected_keepers.go b/x/staking/types/expected_keepers.go index 1c1d7f7de96b..b7479d8fd089 100644 --- a/x/staking/types/expected_keepers.go +++ b/x/staking/types/expected_keepers.go @@ -83,7 +83,7 @@ type DelegationSet interface { fn func(index int64, delegation DelegationI) (stop bool)) } -//_______________________________________________________________________________ +// _______________________________________________________________________________ // Event Hooks // These can be utilized to communicate between a staking keeper and another // keeper which must take particular actions when validators/delegators change diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index e551e752528c..b23a7708f094 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -103,9 +103,7 @@ func (v Validators) Less(i, j int) bool { // Implements sort interface func (v Validators) Swap(i, j int) { - it := v[i] - v[i] = v[j] - v[j] = it + v[i], v[j] = v[j], v[i] } // ValidatorsByVotingPower implements sort.Interface for []Validator based on diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index fa95c4c4aa63..d14cd4e7253d 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -56,10 +56,6 @@ func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { } if !k.HasHandler(plan.Name) { - upgradeMsg := BuildUpgradeNeededMsg(plan) - // We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown - ctx.Logger().Error(upgradeMsg) - // Write the upgrade info to disk. The UpgradeStoreLoader uses this info to perform or skip // store migrations. err := k.DumpUpgradeInfoToDisk(ctx.BlockHeight(), plan.Name) @@ -67,6 +63,10 @@ func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { panic(fmt.Errorf("unable to write upgrade info to filesystem: %s", err.Error())) } + upgradeMsg := BuildUpgradeNeededMsg(plan) + // We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown + ctx.Logger().Error(upgradeMsg) + panic(upgradeMsg) } // We have an upgrade handler for this upgrade name, so apply the upgrade