diff --git a/.github/workflows/build-skip.yml b/.github/workflows/build-skip.yml index bbcd02f30371..c96e8a1022db 100644 --- a/.github/workflows/build-skip.yml +++ b/.github/workflows/build-skip.yml @@ -1,5 +1,6 @@ name: Build SimApp # This workflow allows to skip the build step if the PR does not contain any changes to the code +# See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks on: pull_request: paths-ignore: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf71da5a994d..85ba21342851 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Build run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build - name: Build Legacy diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 968b24c94448..67de44c531e2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/.github/workflows/cosmovisor-release.yml b/.github/workflows/cosmovisor-release.yml index 93d5b23c7554..6160078140e3 100644 --- a/.github/workflows/cosmovisor-release.yml +++ b/.github/workflows/cosmovisor-release.yml @@ -10,7 +10,7 @@ permissions: jobs: goreleaser: permissions: - contents: write # for goreleaser/goreleaser-action to create a GitHub release + contents: write # for goreleaser/goreleaser-action to create a GitHub release runs-on: buildjet-4vcpu-ubuntu-2004 steps: - uses: actions/checkout@v3 @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 # get 'v*.*.*' part from 'cosmovisor/v*.*.*' and save to $GITHUB_ENV - name: Set env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/cosmovisor/}" >> $GITHUB_ENV diff --git a/.github/workflows/dependabot-update-all.yml b/.github/workflows/dependabot-update-all.yml index 6487903e3056..88568333de28 100644 --- a/.github/workflows/dependabot-update-all.yml +++ b/.github/workflows/dependabot-update-all.yml @@ -17,7 +17,7 @@ jobs: token: ${{ secrets.PRBOT_PAT }} - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Extract updated dependency id: deps run: | diff --git a/.github/workflows/dependencies-review.yml b/.github/workflows/dependencies-review.yml index 28411dd5d2a3..c8f362d69961 100644 --- a/.github/workflows/dependencies-review.yml +++ b/.github/workflows/dependencies-review.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: "Checkout Repository" uses: actions/checkout@v3 - name: "Dependency Review" diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index 86949cb84fdc..79f5779abe1a 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -17,6 +17,6 @@ jobs: statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v4.5.0 + - uses: amannn/action-semantic-pull-request@v4.6.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0f0d1c762b7..a386627066a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,14 +13,14 @@ permissions: jobs: release: permissions: - contents: write # for goreleaser/goreleaser-action to create a GitHub release + contents: write # for goreleaser/goreleaser-action to create a GitHub release runs-on: buildjet-4vcpu-ubuntu-2004 steps: - uses: actions/checkout@v3 - name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Unshallow run: git fetch --prune --unshallow - name: Create release diff --git a/.github/workflows/sims-045.yml b/.github/workflows/sims-045.yml index 56824aae7e80..9facf001ceb3 100644 --- a/.github/workflows/sims-045.yml +++ b/.github/workflows/sims-045.yml @@ -21,7 +21,7 @@ jobs: ref: "release/v0.45.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - run: make build install-runsim: @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Install runsim run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 - uses: actions/cache@v3 @@ -49,7 +49,7 @@ jobs: ref: "release/v0.45.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -67,7 +67,7 @@ jobs: ref: "release/v0.45.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -86,7 +86,7 @@ jobs: ref: "release/v0.45.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin diff --git a/.github/workflows/sims-046.yml b/.github/workflows/sims-046.yml index 13665bdcecf3..0565d3903105 100644 --- a/.github/workflows/sims-046.yml +++ b/.github/workflows/sims-046.yml @@ -21,7 +21,7 @@ jobs: ref: "release/v0.46.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - run: make build install-runsim: @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Install runsim run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 - uses: actions/cache@v3 @@ -50,7 +50,7 @@ jobs: ref: "release/v0.46.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -68,7 +68,7 @@ jobs: ref: "release/v0.46.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -86,7 +86,7 @@ jobs: ref: "release/v0.46.x" - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin diff --git a/.github/workflows/sims-nightly.yml b/.github/workflows/sims-nightly.yml index 20c6d5ea424f..fb91263ab603 100644 --- a/.github/workflows/sims-nightly.yml +++ b/.github/workflows/sims-nightly.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Install runsim run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 - uses: actions/cache@v3 @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml index 1eff92a7dacd..2175cf94e8dd 100644 --- a/.github/workflows/sims.yml +++ b/.github/workflows/sims.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: technote-space/get-diff-action@v6.1.0 with: PATTERNS: | @@ -54,7 +54,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -70,7 +70,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin @@ -87,7 +87,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/cache@v3 with: path: ~/go/bin diff --git a/.github/workflows/test-e2e-skip.yml b/.github/workflows/test-e2e-skip.yml index c4622f3dc502..41ab5415225b 100644 --- a/.github/workflows/test-e2e-skip.yml +++ b/.github/workflows/test-e2e-skip.yml @@ -1,5 +1,6 @@ name: Tests E2E # This workflow allows to skip the e2e step if the PR does not contain any changes to the code +# See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks on: pull_request: paths-ignore: diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index d3ce076ecfde..9d398403ba92 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: e2e tests run: | make test-e2e diff --git a/.github/workflows/test-integration-skip.yml b/.github/workflows/test-integration-skip.yml index 3c0fef380327..e8621fdc5e73 100644 --- a/.github/workflows/test-integration-skip.yml +++ b/.github/workflows/test-integration-skip.yml @@ -1,5 +1,6 @@ name: Tests Integration # This workflow allows to skip the integration step if the PR does not contain any changes to the code +# See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks on: pull_request: paths-ignore: diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index f081677c2169..5a8a0dea9577 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: integration tests run: | make test-integration diff --git a/.github/workflows/test-legacy.yml b/.github/workflows/test-legacy.yml index 34cc74a3dd60..227f3987ee28 100644 --- a/.github/workflows/test-legacy.yml +++ b/.github/workflows/test-legacy.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Run submodule tests and create test coverage profile. run: bash scripts/module-tests.sh - uses: actions/upload-artifact@v3 @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Create a file with all core Cosmos SDK pkgs run: go list ./... > pkgs.txt - name: Split pkgs into 4 files @@ -65,7 +65,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: actions/download-artifact@v3 with: name: "${{ github.sha }}-${{ matrix.part }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ff8aacb70ea5..f01ff09d77f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: technote-space/get-diff-action@v6.1.0 id: git_diff with: @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Create a file with all core Cosmos SDK pkgs run: go list ./... > pkgs.txt - name: Split pkgs into 4 files @@ -89,7 +89,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: technote-space/get-diff-action@v6.1.0 with: PATTERNS: | @@ -205,7 +205,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: technote-space/get-diff-action@v6.1.0 id: git_diff with: @@ -238,7 +238,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - uses: technote-space/get-diff-action@v6.1.0 with: PATTERNS: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 54e4d910c43d..3126c32f7043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,34 +53,29 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (ledger) [#12935](https://github.com/cosmos/cosmos-sdk/pull/12935) Generalize Ledger integration to allow for different apps or keytypes that use SECP256k1. * (x/bank) [#11981](https://github.com/cosmos/cosmos-sdk/pull/11981) Create the `SetSendEnabled` endpoint for managing the bank's SendEnabled settings. * (x/auth) [#13210](https://github.com/cosmos/cosmos-sdk/pull/13210) Add `Query/AccountInfo` endpoint for simplified access to basic account info. +* (cli) [#13147](https://github.com/cosmos/cosmos-sdk/pull/13147) Add the `--append` flag to the `sign-batch` CLI cmd to combine the messages and sign those txs which are created with `--generate-only`. ### Improvements +* (deps) [#13397](https://github.com/cosmos/cosmos-sdk/pull/13397) Bump Go version minimum requirement to `1.19`. * [#13323](https://github.com/cosmos/cosmos-sdk/pull/13323) Ensure `withdraw_rewards` rewards are emitted from all actions that result in rewards being withdrawn. * [#13214](https://github.com/cosmos/cosmos-sdk/pull/13214) Add `withdraw-proposal` command to group module's CLI transaction commands. * [#13070](https://github.com/cosmos/cosmos-sdk/pull/13070) Migrate from `gogo/protobuf` to `cosmos/gogoproto`. -* [#12981](https://github.com/cosmos/cosmos-sdk/pull/12981) Return proper error when parsing telemetry configuration. * [#12995](https://github.com/cosmos/cosmos-sdk/pull/12995) Add `FormatTime` and `ParseTimeString` methods. * [#12952](https://github.com/cosmos/cosmos-sdk/pull/12952) Replace keyring module to Cosmos fork. * [#12352](https://github.com/cosmos/cosmos-sdk/pull/12352) Move the `RegisterSwaggerAPI` logic into a separate helper function in the server package. * [#12876](https://github.com/cosmos/cosmos-sdk/pull/12876) Remove proposer-based rewards. * [#12892](https://github.com/cosmos/cosmos-sdk/pull/12892) `make format` now runs only gofumpt and golangci-lint run ./... --fix, replacing `goimports` `gofmt` and `misspell` * [#12846](https://github.com/cosmos/cosmos-sdk/pull/12846) Remove `RandomizedParams` from the `AppModuleSimulation` interface which is no longer needed. -* (events) [#12850](https://github.com/cosmos/cosmos-sdk/pull/12850) Add a new `fee_payer` attribute to the `tx` event that is emitted from the `DeductFeeDecorator` AnteHandler decorator. * (ci) [#12854](https://github.com/cosmos/cosmos-sdk/pull/12854) Use ghcr.io to host the proto builder image. Update proto builder image to go 1.19 * (x/bank) [#12706](https://github.com/cosmos/cosmos-sdk/pull/12706) Added the `chain-id` flag to the `AddTxFlagsToCmd` API. There is no longer a need to explicitly register this flag on commands whens `AddTxFlagsToCmd` is already called. * [#12791](https://github.com/cosmos/cosmos-sdk/pull/12791) Bump the math library used in the sdk and replace old usages of sdk.\* -* (x/params) [#12615](https://github.com/cosmos/cosmos-sdk/pull/12615) Add `GetParamSetIfExists` function to params `Subspace` to prevent panics on breaking changes. * [#12717](https://github.com/cosmos/cosmos-sdk/pull/12717) Use injected encoding params in simapp. -* (x/bank) [#12674](https://github.com/cosmos/cosmos-sdk/pull/12674) Add convenience function `CreatePrefixedAccountStoreKey()` to construct key to access account's balance for a given denom. * [#12702](https://github.com/cosmos/cosmos-sdk/pull/12702) Linting and tidiness, fixed two minor security warnings. * [#12634](https://github.com/cosmos/cosmos-sdk/pull/12634) Move `sdk.Dec` to math package. * [#12596](https://github.com/cosmos/cosmos-sdk/pull/12596) Remove all imports of the non-existent gogo/protobuf v1.3.3 to ease downstream use and go workspaces. * [#12187](https://github.com/cosmos/cosmos-sdk/pull/12187) Add batch operation for x/nft module. -* [#12693](https://github.com/cosmos/cosmos-sdk/pull/12693) Make sure the order of each node is consistent when emitting proto events. * [#12455](https://github.com/cosmos/cosmos-sdk/pull/12455) Show attempts count in error for signing. -* [#12885](https://github.com/cosmos/cosmos-sdk/pull/12885) Amortize cost of processing cache KV store -* [#12953](https://github.com/cosmos/cosmos-sdk/pull/12953) Change the default priority mechanism to be based on gas price. * [#13048](https://github.com/cosmos/cosmos-sdk/pull/13048) Add handling of AccountNumberStoreKeyPrefix to the x/auth simulation decoder. * [#13101](https://github.com/cosmos/cosmos-sdk/pull/13101) Remove weights from `simapp/params` and `testutil/sims`. They are now in their respective modules. * (simapp) [#13107](https://github.com/cosmos/cosmos-sdk/pull/13107) Call `SetIAVLCacheSize` with the configured value in simapp. @@ -113,8 +108,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes -* [#13380](https://github.com/cosmos/cosmos-sdk/pull/13380) Remove deprecated `sdk.NewLevelDB`. -* [#13378](https://github.com/cosmos/cosmos-sdk/pull/13378) Move `simapp.App` to `runtime.AppI`. `simapp.App` is now an alias of `runtime.AppI`. +* (simapp) [#13402](https://github.com/cosmos/cosmos-sdk/pull/13402) Move simulation flags to `x/simulation/client/cli`. +* (simapp) [#13402](https://github.com/cosmos/cosmos-sdk/pull/13402) Move simulation helpers functions (`SetupSimulation`, `SimulationOperations`, `CheckExportSimulation`, `PrintStats`, `GetSimulationLog`) to `testutil/sims`. +* (simapp) [#13402](https://github.com/cosmos/cosmos-sdk/pull/13402) Move `testutil/rest` package to `testutil`. +* (types) [#13380](https://github.com/cosmos/cosmos-sdk/pull/13380) Remove deprecated `sdk.NewLevelDB`. +* (simapp) [#13378](https://github.com/cosmos/cosmos-sdk/pull/13378) Move `simapp.App` to `runtime.AppI`. * (tx) [#12659](https://github.com/cosmos/cosmos-sdk/pull/12659) Remove broadcast mode `block`. * (db) [#13370](https://github.com/cosmos/cosmos-sdk/pull/13370) remove storev2alpha1, see also https://github.com/cosmos/cosmos-sdk/pull/13371 * (context) [#13063](https://github.com/cosmos/cosmos-sdk/pull/13063) Update `Context#CacheContext` to automatically emit all events on the parent context's `EventManager`. @@ -150,6 +148,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (codec) [#12964](https://github.com/cosmos/cosmos-sdk/pull/12964) `ProtoCodec.MarshalInterface` now returns an error when serializing unregistered types and a subsequent `ProtoCodec.UnmarshalInterface` would fail. * (x/staking) [#12973](https://github.com/cosmos/cosmos-sdk/pull/12973) Removed `stakingkeeper.RandomValidator`. Use `testutil.RandSliceElem(r, sk.GetAllValidators(ctx))` instead. * (x/gov) [13160](https://github.com/cosmos/cosmos-sdk/pull/13160) Remove custom marshaling of proposl and voteoption. +* (x/auth) [13411](https://github.com/cosmos/cosmos-sdk/pull/13411) Change account id to use uint64 in `AccountAddressByID` grpc query. * (types) [13430](https://github.com/cosmos/cosmos-sdk/pull/13430) Remove unused code `ResponseCheckTx` and `ResponseDeliverTx` ### CLI Breaking Changes @@ -168,14 +167,15 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/staking) [#12303](https://github.com/cosmos/cosmos-sdk/pull/12303) Use bytes instead of string comparison in delete validator queue * (x/auth/tx) [#12474](https://github.com/cosmos/cosmos-sdk/pull/12474) Remove condition in GetTxsEvent that disallowed multiple equal signs, which would break event queries with base64 strings (i.e. query by signature). * (store/rootmulti) [#12487](https://github.com/cosmos/cosmos-sdk/pull/12487) Fix non-deterministic map iteration. -* (x/group) [#12888](https://github.com/cosmos/cosmos-sdk/pull/12888) Fix event propagation to the current context of `x/group` message execution `[]sdk.Result`. * (sdk/dec_coins) [#12903](https://github.com/cosmos/cosmos-sdk/pull/12903) Fix nil `DecCoin` creation when converting `Coins` to `DecCoins` -* (x/upgrade) [#12906](https://github.com/cosmos/cosmos-sdk/pull/12906) Fix upgrade failure by moving downgrade verification logic after store migration. * (store) [#12945](https://github.com/cosmos/cosmos-sdk/pull/12945) Fix nil end semantics in store/cachekv/iterator when iterating a dirty cache. * (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression. * (x/gov) [#13051](https://github.com/cosmos/cosmos-sdk/pull/13051) In SubmitPropsal, when a legacy msg fails it's handler call, wrap the error as ErrInvalidProposalContent (instead of ErrNoProposalHandlerExists). * (x/gov) [#13045](https://github.com/cosmos/cosmos-sdk/pull/13045) Fix gov migrations for v3(0.46). * (Store) [#13334](https://github.com/cosmos/cosmos-sdk/pull/13334) Call streaming listeners for deliver tx event, it was removed accidentally. +* (grpc) [#13352](https://github.com/cosmos/cosmos-sdk/pull/13352) fix grpc query panic that could crash the node. +* (snapshot) [#13400](https://github.com/cosmos/cosmos-sdk/pull/13400) Fix snapshot checksum issue in golang 1.19. +* (grpc) [#13418](https://github.com/cosmos/cosmos-sdk/pull/13418) Add close for grpc only mode. ### Deprecated @@ -184,6 +184,25 @@ Ref: https://keepachangelog.com/en/1.0.0/ Setting can be done using MsgSetSendEnabled as a governance proposal. A SendEnabled query has been added to both GRPC and CLI. +## [v0.46.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.1) - 2022-08-24 + +### Improvements + +* [#12953](https://github.com/cosmos/cosmos-sdk/pull/12953) Change the default priority mechanism to be based on gas price. +* [#12981](https://github.com/cosmos/cosmos-sdk/pull/12981) Return proper error when parsing telemetry configuration. +* [#12969](https://github.com/cosmos/cosmos-sdk/pull/12969) Bump Tendermint to `v0.34.21` and IAVL to `v0.19.1`. +* [#12885](https://github.com/cosmos/cosmos-sdk/pull/12885) Amortize cost of processing cache KV store. +* (events) [#12850](https://github.com/cosmos/cosmos-sdk/pull/12850) Add a new `fee_payer` attribute to the `tx` event that is emitted from the `DeductFeeDecorator` AnteHandler decorator. +* (x/params) [#12615](https://github.com/cosmos/cosmos-sdk/pull/12615) Add `GetParamSetIfExists` function to params `Subspace` to prevent panics on breaking changes. +* (x/bank) [#12674](https://github.com/cosmos/cosmos-sdk/pull/12674) Add convenience function `CreatePrefixedAccountStoreKey()` to construct key to access account's balance for a given denom. +* [#12877](https://github.com/cosmos/cosmos-sdk/pull/12877) Bumped cosmossdk.io/math to v1.0.0-beta.3 +* [#12693](https://github.com/cosmos/cosmos-sdk/pull/12693) Make sure the order of each node is consistent when emitting proto events. + +### Bug Fixes + +* (x/group) [#12888](https://github.com/cosmos/cosmos-sdk/pull/12888) Fix event propagation to the current context of `x/group` message execution `[]sdk.Result`. +* (x/upgrade) [#12906](https://github.com/cosmos/cosmos-sdk/pull/12906) Fix upgrade failure by moving downgrade verification logic after store migration. + ## [v0.46.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.0) - 2022-07-26 ### Features diff --git a/Dockerfile b/Dockerfile index b4933b12af95..84a7393ea36d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ # > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simappcli:/root/.simapp simapp simd keys add foo # > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simappcli:/root/.simapp simapp simd keys list # TODO: demo connecting rest-server (or is this in server now?) -FROM golang:1.18-alpine AS build-env +FROM golang:1.19-alpine AS build-env # Install minimum necessary dependencies ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 diff --git a/Makefile b/Makefile index 249e00d3bc75..40dce3fc3fb7 100644 --- a/Makefile +++ b/Makefile @@ -146,6 +146,7 @@ cosmovisor: mocks: $(MOCKS_DIR) + @go install github.com/golang/mock/mockgen@v1.6.0 sh ./scripts/mockgen.sh .PHONY: mocks diff --git a/README.md b/README.md index 666b792fa782..9b8d777e06aa 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The Cosmos SDK is a framework for building blockchain applications. [Tendermint **WARNING**: The Cosmos SDK has mostly stabilized, but we are still making some breaking changes. -**Note**: Requires [Go 1.18+](https://go.dev/dl) +**Note**: Requires [Go 1.19+](https://go.dev/dl) ## Quick Start @@ -53,7 +53,7 @@ For more information, see the [Cosmos SDK Documentation](https://docs.cosmos.net ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md) for details how to contribute and participate in our [dev calls](./CONTRIBUTING.md#teams-dev-calls). +See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on how to contribute and participate in our [dev calls](./CONTRIBUTING.md#teams-dev-calls). If you want to follow the updates or learn more about the latest design then join our [Discord](https://discord.com/invite/cosmosnetwork). ## Tools and Frameworks diff --git a/UPGRADING.md b/UPGRADING.md index ea8346c4a579..159d3c4136c2 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -14,18 +14,22 @@ Remove `Querier`, `Route` and `LegacyQuerier` from the app module interface. Thi ### SimApp +The `simapp` package **should not be imported in your own app**. Instead, you should import the `runtime.AppI` interface, that defines an `App`, and use the [`simtestutil` package](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/testutil/sims) for application testing. + +#### App Wiring + SimApp's `app.go` is now using [App Wiring](https://docs.cosmos.network/main/building-chain/depinject.html), the dependency injection framework of the Cosmos SDK. This means that modules are injected directly into SimApp thanks to a [configuration file](https://github.com/cosmos/cosmos-sdk/blob/main/simapp/app_config.go). The old behavior is preserved and can still be used, without the dependency injection framework, as shows [`app_legacy.go`](https://github.com/cosmos/cosmos-sdk/blob/main/simapp/app_legacy.go). +#### Constructor + The constructor, `NewSimApp` has been simplified: * `NewSimApp` does not take encoding parameters (`encodingConfig`) as input, instead the encoding parameters are injected (when using app wiring), or directly created in the constructor. Instead, we can instantiate `SimApp` for getting the encoding configuration. * `NewSimApp` now uses `AppOptions` for getting the home path (`homePath`) and the invariant checks period (`invCheckPeriod`). These were unnecessary given as arguments as they were already present in the `AppOptions`. -SimApp should not be imported in your own app. Instead, you should import the `runtime.AppI` interface, that defines an `App`, and use the [`simtestutil` package](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/testutil/sims) for application testing. - -### Encoding +#### Encoding `simapp.MakeTestEncodingConfig()` was deprecated and has been removed. Instead you can use the `TestEncodingConfig` from the `types/module/testutil` package. This means you can replace your usage of `simapp.MakeTestEncodingConfig` in tests to `moduletestutil.MakeTestEncodingConfig`, which takes a series of relevant `AppModuleBasic` as input (the module being tested and any potential dependencies). @@ -37,14 +41,20 @@ The SDK has migrated from `gogo/protobuf` (which is currently unmaintained), to This means you should replace all imports of `github.com/gogo/protobuf` to `github.com/cosmos/gogoproto`. This allows you to remove the replace directive `replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1` from your `go.mod` file. +Please use the `ghcr.io/cosmos/proto-builder` image (version >= `0.11.0`) for generating protobuf files. + ### Transactions +#### Broadcast Mode + Broadcast mode `block` was deprecated and has been removed. Please use `sync` mode instead. -When upgrading your tests from `block` to `sync` and checking for a transaction code, you might need to query the transaction first (with its hash) to get the correct code. +When upgrading your tests from `block` to `sync` and checking for a transaction code, you need to query the transaction first (with its hash) to get the correct code. -### `x/gov` +### Modules -#### Minimum Proposal Deposit At Time of Submission +#### `x/gov` + +##### Minimum Proposal Deposit At Time of Submission The `gov` module has been updated to support a minimum proposal deposit at submission time. It is determined by a new parameter called `MinInitialDepositRatio`. When multiplied by the existing `MinDeposit` parameter, it produces @@ -91,6 +101,8 @@ Additionally, new packages have been introduced in order to further split the co * `errors` should replace `types/errors` when registering errors or wrapping SDK errors. * `math` contains the `Int` or `Uint` types that are used in the SDK. +* `x/nft` an NFT base module. +* `x/group` a group module allowing to create DAOs, multisig and policies. Greatly composes with `x/authz`. #### `x/authz` @@ -177,5 +189,4 @@ message MsgSetWithdrawAddress { - When clients interract with a node they are required to set a codec in in the grpc.Dial. More information can be found in this [doc](https://docs.cosmos.network/v0.46/run-node/interact-node.html#programmatically-via-go). diff --git a/api/cosmos/auth/v1beta1/query.pulsar.go b/api/cosmos/auth/v1beta1/query.pulsar.go index 799865e0bdfe..6336b68e6d06 100644 --- a/api/cosmos/auth/v1beta1/query.pulsar.go +++ b/api/cosmos/auth/v1beta1/query.pulsar.go @@ -6058,8 +6058,8 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Interface() protoreflect // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_QueryAccountAddressByIDRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != int64(0) { - value := protoreflect.ValueOfInt64(x.Id) + if x.Id != uint64(0) { + value := protoreflect.ValueOfUint64(x.Id) if !f(fd_QueryAccountAddressByIDRequest_id, value) { return } @@ -6080,7 +6080,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Range(f func(protoreflec func (x *fastReflection_QueryAccountAddressByIDRequest) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "cosmos.auth.v1beta1.QueryAccountAddressByIDRequest.id": - return x.Id != int64(0) + return x.Id != uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.QueryAccountAddressByIDRequest")) @@ -6098,7 +6098,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Has(fd protoreflect.Fiel func (x *fastReflection_QueryAccountAddressByIDRequest) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "cosmos.auth.v1beta1.QueryAccountAddressByIDRequest.id": - x.Id = int64(0) + x.Id = uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.QueryAccountAddressByIDRequest")) @@ -6117,7 +6117,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Get(descriptor protorefl switch descriptor.FullName() { case "cosmos.auth.v1beta1.QueryAccountAddressByIDRequest.id": value := x.Id - return protoreflect.ValueOfInt64(value) + return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.QueryAccountAddressByIDRequest")) @@ -6139,7 +6139,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Get(descriptor protorefl func (x *fastReflection_QueryAccountAddressByIDRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { case "cosmos.auth.v1beta1.QueryAccountAddressByIDRequest.id": - x.Id = value.Int() + x.Id = value.Uint() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.QueryAccountAddressByIDRequest")) @@ -6176,7 +6176,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) Mutable(fd protoreflect. func (x *fastReflection_QueryAccountAddressByIDRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { case "cosmos.auth.v1beta1.QueryAccountAddressByIDRequest.id": - return protoreflect.ValueOfInt64(int64(0)) + return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.QueryAccountAddressByIDRequest")) @@ -6346,7 +6346,7 @@ func (x *fastReflection_QueryAccountAddressByIDRequest) ProtoMethods() *protoifa } b := dAtA[iNdEx] iNdEx++ - x.Id |= int64(b&0x7F) << shift + x.Id |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -8191,7 +8191,7 @@ type QueryAccountAddressByIDRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` } func (x *QueryAccountAddressByIDRequest) Reset() { @@ -8214,7 +8214,7 @@ func (*QueryAccountAddressByIDRequest) Descriptor() ([]byte, []int) { return file_cosmos_auth_v1beta1_query_proto_rawDescGZIP(), []int{14} } -func (x *QueryAccountAddressByIDRequest) GetId() int64 { +func (x *QueryAccountAddressByIDRequest) GetId() uint64 { if x != nil { return x.Id } @@ -8417,7 +8417,7 @@ var file_cosmos_auth_v1beta1_query_proto_rawDesc = []byte{ 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x30, 0x0a, 0x1e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x1f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, diff --git a/api/cosmos/base/store/v1beta1/commit_info.pulsar.go b/api/cosmos/base/store/v1beta1/commit_info.pulsar.go index 02bfa7426cba..4e259d858705 100644 --- a/api/cosmos/base/store/v1beta1/commit_info.pulsar.go +++ b/api/cosmos/base/store/v1beta1/commit_info.pulsar.go @@ -1627,7 +1627,7 @@ func (x *StoreInfo) GetCommitId() *CommitID { return nil } -// CommitID defines the committment information when a specific store is +// CommitID defines the commitment information when a specific store is // committed. type CommitID struct { state protoimpl.MessageState diff --git a/api/cosmos/base/tendermint/v1beta1/query.pulsar.go b/api/cosmos/base/tendermint/v1beta1/query.pulsar.go index 9d037fff7d1c..e81922e1118c 100644 --- a/api/cosmos/base/tendermint/v1beta1/query.pulsar.go +++ b/api/cosmos/base/tendermint/v1beta1/query.pulsar.go @@ -11261,7 +11261,7 @@ func (x *ABCIQueryResponse) GetCodespace() string { } // ProofOp defines an operation used for calculating Merkle root. The data could -// be arbitrary format, providing nessecary data for example neighbouring node +// be arbitrary format, providing necessary data for example neighbouring node // hash. // // Note: This type is a duplicate of the ProofOp proto type defined in Tendermint. diff --git a/api/cosmos/distribution/v1beta1/genesis.pulsar.go b/api/cosmos/distribution/v1beta1/genesis.pulsar.go index b8a416f62970..63a1b31088b9 100644 --- a/api/cosmos/distribution/v1beta1/genesis.pulsar.go +++ b/api/cosmos/distribution/v1beta1/genesis.pulsar.go @@ -5373,7 +5373,7 @@ type ValidatorOutstandingRewardsRecord struct { // validator_address is the address of the validator. ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` - // outstanding_rewards represents the oustanding rewards of a validator. + // outstanding_rewards represents the outstanding rewards of a validator. OutstandingRewards []*v1beta1.DecCoin `protobuf:"bytes,2,rep,name=outstanding_rewards,json=outstandingRewards,proto3" json:"outstanding_rewards,omitempty"` } @@ -5623,7 +5623,7 @@ type ValidatorSlashEventRecord struct { // validator_address is the address of the validator. ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` - // height defines the block height at which the slash event occured. + // height defines the block height at which the slash event occurred. Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` // period is the period of the slash event. Period uint64 `protobuf:"varint,3,opt,name=period,proto3" json:"period,omitempty"` diff --git a/api/cosmos/distribution/v1beta1/query.pulsar.go b/api/cosmos/distribution/v1beta1/query.pulsar.go index 531bf3194fe5..40a22c3566d4 100644 --- a/api/cosmos/distribution/v1beta1/query.pulsar.go +++ b/api/cosmos/distribution/v1beta1/query.pulsar.go @@ -9546,7 +9546,7 @@ type QueryValidatorDistributionInfoResponse struct { OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` // self_bond_rewards defines the self delegations rewards. SelfBondRewards []*v1beta1.DecCoin `protobuf:"bytes,2,rep,name=self_bond_rewards,json=selfBondRewards,proto3" json:"self_bond_rewards,omitempty"` - // commission defines the commision the validator received. + // commission defines the commission the validator received. Commission []*v1beta1.DecCoin `protobuf:"bytes,3,rep,name=commission,proto3" json:"commission,omitempty"` } @@ -9711,7 +9711,7 @@ type QueryValidatorCommissionResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // commission defines the commision the validator received. + // commission defines the commission the validator received. Commission *ValidatorAccumulatedCommission `protobuf:"bytes,1,opt,name=commission,proto3" json:"commission,omitempty"` } diff --git a/api/cosmos/gov/v1beta1/genesis.pulsar.go b/api/cosmos/gov/v1beta1/genesis.pulsar.go index c34920f18ae2..f12d7cb9e3fe 100644 --- a/api/cosmos/gov/v1beta1/genesis.pulsar.go +++ b/api/cosmos/gov/v1beta1/genesis.pulsar.go @@ -1095,11 +1095,11 @@ type GenesisState struct { Votes []*Vote `protobuf:"bytes,3,rep,name=votes,proto3" json:"votes,omitempty"` // proposals defines all the proposals present at genesis. Proposals []*Proposal `protobuf:"bytes,4,rep,name=proposals,proto3" json:"proposals,omitempty"` - // params defines all the paramaters of related to deposit. + // params defines all the parameters of related to deposit. DepositParams *DepositParams `protobuf:"bytes,5,opt,name=deposit_params,json=depositParams,proto3" json:"deposit_params,omitempty"` - // params defines all the paramaters of related to voting. + // params defines all the parameters of related to voting. VotingParams *VotingParams `protobuf:"bytes,6,opt,name=voting_params,json=votingParams,proto3" json:"voting_params,omitempty"` - // params defines all the paramaters of related to tally. + // params defines all the parameters of related to tally. TallyParams *TallyParams `protobuf:"bytes,7,opt,name=tally_params,json=tallyParams,proto3" json:"tally_params,omitempty"` } diff --git a/api/cosmos/group/v1/types.pulsar.go b/api/cosmos/group/v1/types.pulsar.go index ac3083c3a891..a33c437d9c4e 100644 --- a/api/cosmos/group/v1/types.pulsar.go +++ b/api/cosmos/group/v1/types.pulsar.go @@ -7533,10 +7533,10 @@ func (x *MemberRequest) GetMetadata() string { // ThresholdDecisionPolicy is a decision policy where a proposal passes when it // satisfies the two following conditions: -// 1. The sum of all `YES` voters' weights is greater or equal than the defined -// `threshold`. -// 2. The voting and execution periods of the proposal respect the parameters -// given by `windows`. +// 1. The sum of all `YES` voters' weights is greater or equal than the defined +// `threshold`. +// 2. The voting and execution periods of the proposal respect the parameters +// given by `windows`. type ThresholdDecisionPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7585,10 +7585,10 @@ func (x *ThresholdDecisionPolicy) GetWindows() *DecisionPolicyWindows { // PercentageDecisionPolicy is a decision policy where a proposal passes when // it satisfies the two following conditions: -// 1. The percentage of all `YES` voters' weights out of the total group weight -// is greater or equal than the given `percentage`. -// 2. The voting and execution periods of the proposal respect the parameters -// given by `windows`. +// 1. The percentage of all `YES` voters' weights out of the total group weight +// is greater or equal than the given `percentage`. +// 2. The voting and execution periods of the proposal respect the parameters +// given by `windows`. type PercentageDecisionPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7950,7 +7950,7 @@ type Proposal struct { // whichever happens first. FinalTallyResult *TallyResult `protobuf:"bytes,9,opt,name=final_tally_result,json=finalTallyResult,proto3" json:"final_tally_result,omitempty"` // voting_period_end is the timestamp before which voting must be done. - // Unless a successfull MsgExec is called before (to execute a proposal whose + // Unless a successful MsgExec is called before (to execute a proposal whose // tally is successful before the voting period ends), tallying will be done // at this point, and the `final_tally_result`and `status` fields will be // accordingly updated. diff --git a/api/go.mod b/api/go.mod index 2326d3ddb2bd..e3e7cf7da8f9 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/api -go 1.18 +go 1.19 require ( github.com/cosmos/cosmos-proto v1.0.0-alpha7 diff --git a/api/tendermint/crypto/proof.pulsar.go b/api/tendermint/crypto/proof.pulsar.go index a3128844e44e..dfaf424608db 100644 --- a/api/tendermint/crypto/proof.pulsar.go +++ b/api/tendermint/crypto/proof.pulsar.go @@ -2919,7 +2919,7 @@ func (x *DominoOp) GetOutput() string { } // ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data +// The data could be arbitrary format, providing necessary data // for example neighbouring node hash type ProofOp struct { state protoimpl.MessageState diff --git a/baseapp/abci.go b/baseapp/abci.go index 39e8bf81c5e4..4f52136fac10 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -232,15 +232,41 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc return res } -// PrepareProposal implements the ability for the application to verify and/or modify transactions in a block proposal. +// PrepareProposal implements the PrepareProposal ABCI method and returns a +// ResponsePrepareProposal object to the client. The PrepareProposal method is +// responsible for allowing the block proposer to perform application-dependent +// work in a block before proposing it. +// +// Transactions can be modified, removed, or added by the application. Since the +// application maintains it's own local mempool, it will ignore the transactions +// provided to it in RequestPrepareProposal. Instead, it will determine which +// transactions to return based on the mempool's semantics and the MaxTxBytes +// provided by the client's request. +// +// Note, there is no need to execute the transactions for validity as they have +// already passed CheckTx. +// +// Ref: https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-060-abci-1.0.md +// Ref: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci%2B%2B_basic_concepts.md func (app *BaseApp) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { - // treated as a noop until app side mempool is implemented + // TODO: Implement. return abci.ResponsePrepareProposal{Txs: req.Txs} } -// ProcessProposal implements the ability for the application to verify transactions in a block proposal, and decide if they should accept the block or not. +// ProcessProposal implements the ProcessProposal ABCI method and returns a +// ResponseProcessProposal object to the client. The ProcessProposal method is +// responsible for allowing execution of application-dependent work in a proposed +// block. Note, the application defines the exact implementation details of +// ProcessProposal. In general, the application must at the very least ensure +// that all transactions are valid. If all transactions are valid, then we inform +// Tendermint that the Status is ACCEPT. However, the application is also able +// to implement optimizations such as executing the entire proposed block +// immediately. It may even execute the block in parallel. +// +// Ref: https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-060-abci-1.0.md +// Ref: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci%2B%2B_basic_concepts.md func (app *BaseApp) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { - // accept all proposed blocks until app side mempool is implemented + // TODO: Implement. return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} } diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index deeb4fc9e72d..247099390985 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -299,6 +299,7 @@ func (app *BaseApp) SnapshotManager() *snapshots.Manager { // LoadVersion loads the BaseApp application version. It will panic if called // more than once on a running baseapp. func (app *BaseApp) LoadVersion(version int64) error { + app.logger.Info("NOTICE: this could take a long time to migrate IAVL store to fastnode if you enable Fast Node.\n") err := app.cms.LoadVersion(version) if err != nil { return fmt.Errorf("failed to load version %d: %w", version, err) diff --git a/baseapp/deliver_tx_test.go b/baseapp/deliver_tx_test.go index 7eacbee32c65..453ddab35c48 100644 --- a/baseapp/deliver_tx_test.go +++ b/baseapp/deliver_tx_test.go @@ -666,7 +666,7 @@ func TestSnapshotWithPruning(t *testing.T) { pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing), }, expectedSnapshots: []*abci.Snapshot{ - {Height: 20, Format: 2, Chunks: 5}, + {Height: 20, Format: snapshottypes.CurrentFormat, Chunks: 5}, }, }, "prune everything with snapshot": { @@ -678,7 +678,7 @@ func TestSnapshotWithPruning(t *testing.T) { pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningEverything), }, expectedSnapshots: []*abci.Snapshot{ - {Height: 20, Format: 2, Chunks: 5}, + {Height: 20, Format: snapshottypes.CurrentFormat, Chunks: 5}, }, }, "default pruning with snapshot": { @@ -690,7 +690,7 @@ func TestSnapshotWithPruning(t *testing.T) { pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningDefault), }, expectedSnapshots: []*abci.Snapshot{ - {Height: 20, Format: 2, Chunks: 5}, + {Height: 20, Format: snapshottypes.CurrentFormat, Chunks: 5}, }, }, "custom": { @@ -702,8 +702,8 @@ func TestSnapshotWithPruning(t *testing.T) { pruningOpts: pruningtypes.NewCustomPruningOptions(12, 12), }, expectedSnapshots: []*abci.Snapshot{ - {Height: 25, Format: 2, Chunks: 6}, - {Height: 20, Format: 2, Chunks: 5}, + {Height: 25, Format: snapshottypes.CurrentFormat, Chunks: 6}, + {Height: 20, Format: snapshottypes.CurrentFormat, Chunks: 5}, }, }, "no snapshots": { @@ -724,9 +724,9 @@ func TestSnapshotWithPruning(t *testing.T) { pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing), }, expectedSnapshots: []*abci.Snapshot{ - {Height: 9, Format: 2, Chunks: 2}, - {Height: 6, Format: 2, Chunks: 2}, - {Height: 3, Format: 2, Chunks: 1}, + {Height: 9, Format: snapshottypes.CurrentFormat, Chunks: 2}, + {Height: 6, Format: snapshottypes.CurrentFormat, Chunks: 2}, + {Height: 3, Format: snapshottypes.CurrentFormat, Chunks: 1}, }, }, } @@ -788,7 +788,7 @@ func TestLoadSnapshotChunk(t *testing.T) { blocks: 2, blockTxs: 5, snapshotInterval: 2, - snapshotKeepRecent: 2, + snapshotKeepRecent: snapshottypes.CurrentFormat, pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing), } app, err := setupBaseAppWithSnapshots(t, setupConfig) @@ -802,7 +802,7 @@ func TestLoadSnapshotChunk(t *testing.T) { }{ "Existing snapshot": {2, snapshottypes.CurrentFormat, 1, false}, "Missing height": {100, snapshottypes.CurrentFormat, 1, true}, - "Missing format": {2, 3, 1, true}, + "Missing format": {2, snapshottypes.CurrentFormat + 1, 1, true}, "Missing chunk": {2, snapshottypes.CurrentFormat, 9, true}, "Zero height": {0, snapshottypes.CurrentFormat, 1, true}, "Zero format": {2, 0, 1, true}, diff --git a/baseapp/grpcrouter_test.go b/baseapp/grpcrouter_test.go index 89b419e18c75..7a672b10b54f 100644 --- a/baseapp/grpcrouter_test.go +++ b/baseapp/grpcrouter_test.go @@ -35,9 +35,9 @@ func TestGRPCQueryRouter(t *testing.T) { require.NotNil(t, res) require.Equal(t, "hello", res.Message) - require.Panics(t, func() { - _, _ = client.Echo(context.Background(), nil) - }) + res, err = client.Echo(context.Background(), nil) + require.Nil(t, err) + require.Empty(t, res.Message) res2, err := client.SayHello(context.Background(), &testdata.SayHelloRequest{Name: "Foo"}) require.Nil(t, err) @@ -153,9 +153,9 @@ func testQueryDataRacesSameHandler(t *testing.T, makeClientConn func(*baseapp.GR require.NotNil(t, res) require.Equal(t, "hello", res.Message) - require.Panics(t, func() { - _, _ = client.Echo(context.Background(), nil) - }) + res, err = client.Echo(context.Background(), nil) + require.Nil(t, err) + require.Empty(t, res.Message) res2, err := client.SayHello(context.Background(), &testdata.SayHelloRequest{Name: "Foo"}) require.Nil(t, err) diff --git a/client/v2/go.mod b/client/v2/go.mod index 642b8cb3c9ee..47ec2f82ef01 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/client/v2 -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/codec/proto_codec.go b/codec/proto_codec.go index 75815eaa8251..b1d4eb45183e 100644 --- a/codec/proto_codec.go +++ b/codec/proto_codec.go @@ -43,6 +43,11 @@ func NewProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec { // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.MarshalInterface func (pc *ProtoCodec) Marshal(o ProtoMarshaler) ([]byte, error) { + // Size() check can catch the typed nil value. + if o == nil || o.Size() == 0 { + // return empty bytes instead of nil, because nil has special meaning in places like store.Set + return []byte{}, nil + } return o.Marshal() } diff --git a/codec/proto_codec_test.go b/codec/proto_codec_test.go index 69e9066733e6..b661db1fe70c 100644 --- a/codec/proto_codec_test.go +++ b/codec/proto_codec_test.go @@ -3,15 +3,20 @@ package codec_test import ( "errors" "fmt" + "math" "reflect" "testing" "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/encoding" + "google.golang.org/grpc/status" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) func createTestInterfaceRegistry() types.InterfaceRegistry { @@ -109,6 +114,28 @@ func TestProtoCodecMarshal(t *testing.T) { err = cartoonCdc.UnmarshalInterface(bz, &cartoon) require.NoError(t, err) + + // test typed nil input shouldn't panic + var v *banktypes.QueryBalanceResponse + bz, err = grpcServerEncode(cartoonCdc.GRPCCodec(), v) + require.NoError(t, err) + require.Empty(t, bz) +} + +// Emulate grpc server implementation +// https://github.com/grpc/grpc-go/blob/b1d7f56b81b7902d871111b82dec6ba45f854ede/rpc_util.go#L590 +func grpcServerEncode(c encoding.Codec, msg interface{}) ([]byte, error) { + if msg == nil { // NOTE: typed nils will not be caught by this check + return nil, nil + } + b, err := c.Marshal(msg) + if err != nil { + return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error()) + } + if uint(len(b)) > math.MaxUint32 { + return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b)) + } + return b, nil } func TestProtoCodecUnmarshalLengthPrefixedChecks(t *testing.T) { diff --git a/contrib/images/simd-dlv/Dockerfile b/contrib/images/simd-dlv/Dockerfile index 3227b80c46a1..1a25c4d31a7a 100644 --- a/contrib/images/simd-dlv/Dockerfile +++ b/contrib/images/simd-dlv/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine AS build +FROM golang:1.19-alpine AS build RUN apk add build-base git linux-headers libc-dev RUN go install github.com/go-delve/delve/cmd/dlv@latest diff --git a/contrib/images/simd-env/Dockerfile b/contrib/images/simd-env/Dockerfile index c634e39e1ac2..5df38271cd53 100644 --- a/contrib/images/simd-env/Dockerfile +++ b/contrib/images/simd-env/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine AS build +FROM golang:1.19-alpine AS build RUN apk add build-base git linux-headers diff --git a/contrib/rosetta/rosetta-ci/Dockerfile b/contrib/rosetta/rosetta-ci/Dockerfile index 85a59b60200d..68f42cd04e05 100644 --- a/contrib/rosetta/rosetta-ci/Dockerfile +++ b/contrib/rosetta/rosetta-ci/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine as build +FROM golang:1.19-alpine as build RUN apk add --no-cache tar git diff --git a/contrib/rosetta/rosetta-cli/Dockerfile b/contrib/rosetta/rosetta-cli/Dockerfile index da6ef2879239..f4fc15d9bced 100644 --- a/contrib/rosetta/rosetta-cli/Dockerfile +++ b/contrib/rosetta/rosetta-cli/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine as build +FROM golang:1.19-alpine as build RUN apk add git gcc libc-dev --no-cache diff --git a/core/go.mod b/core/go.mod index 45f451209088..4a27ee31d81c 100644 --- a/core/go.mod +++ b/core/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/core -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/cosmovisor/go.mod b/cosmovisor/go.mod index 0dd17f08d480..0b85ad3744d4 100644 --- a/cosmovisor/go.mod +++ b/cosmovisor/go.mod @@ -1,6 +1,6 @@ module github.com/cosmos/cosmos-sdk/cosmovisor -go 1.18 +go 1.19 require ( github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20220909113810-4882f933b1a1 diff --git a/depinject/go.mod b/depinject/go.mod index e4a90d702124..4def0674d898 100644 --- a/depinject/go.mod +++ b/depinject/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/depinject -go 1.18 +go 1.19 require ( github.com/pkg/errors v0.9.1 diff --git a/docs/spec/store/README.md b/docs/spec/store/README.md index cd9d23fc454d..4ca5775a2e53 100644 --- a/docs/spec/store/README.md +++ b/docs/spec/store/README.md @@ -96,6 +96,22 @@ the typical abstraction layer in order is defined as follows: iavl.Store <- cachekv.Store <- gaskv.Store <- cachemulti.Store <- rootmulti.Store ``` +### Concurrent use of IAVL store + +The tree under `iavl.Store` is not safe for concurrent use. It is the +responsibility of the caller to ensure that concurrent access to the store is +not performed. + +The main issue with concurrent use is when data is written at the same time as +it's being iterated over. Doing so will cause a irrecoverable fatal error because +of concurrent reads and writes to an internal map. + +Although it's not recommended, you can iterate through values while writing to +it by disabling "FastNode" **without guarantees that the values being written will +be returned during the iteration** (if you need this, you might want to reconsider +the design of your application). This is done by setting `iavl-disable-fastnode` +to `true` in the config TOML file. + ### `cachekv.Store` The `cachekv.Store` store wraps an underlying `KVStore`, typically a `iavl.Store` diff --git a/errors/go.mod b/errors/go.mod index 71812bdf0755..0b8b26cd21b4 100644 --- a/errors/go.mod +++ b/errors/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/errors -go 1.18 +go 1.19 require ( github.com/pkg/errors v0.9.1 diff --git a/go.mod b/go.mod index defdc4b8c9a2..dab3baf3719e 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -go 1.18 +go 1.19 module github.com/cosmos/cosmos-sdk diff --git a/go.work.example b/go.work.example index b1309636c032..60ddf15344ca 100644 --- a/go.work.example +++ b/go.work.example @@ -1,4 +1,4 @@ -go 1.18 +go 1.19 use ( . diff --git a/math/go.mod b/math/go.mod index 47389e7c2afe..eeaab7865e17 100644 --- a/math/go.mod +++ b/math/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/math -go 1.18 +go 1.19 require ( github.com/stretchr/testify v1.8.0 diff --git a/orm/go.mod b/orm/go.mod index e1b1aed00c16..f16fa81da489 100644 --- a/orm/go.mod +++ b/orm/go.mod @@ -1,6 +1,6 @@ module github.com/cosmos/cosmos-sdk/orm -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/proto/cosmos/auth/v1beta1/query.proto b/proto/cosmos/auth/v1beta1/query.proto index 8cfa1fab0fcf..656f5d4bd719 100644 --- a/proto/cosmos/auth/v1beta1/query.proto +++ b/proto/cosmos/auth/v1beta1/query.proto @@ -181,7 +181,7 @@ message AddressStringToBytesResponse { // QueryAccountAddressByIDRequest is the request type for AccountAddressByID rpc method message QueryAccountAddressByIDRequest { - int64 id = 1; + uint64 id = 1; } // QueryAccountAddressByIDResponse is the response type for AccountAddressByID rpc method diff --git a/proto/cosmos/base/store/v1beta1/commit_info.proto b/proto/cosmos/base/store/v1beta1/commit_info.proto index 98a33d30e754..b7b6a1972fa3 100644 --- a/proto/cosmos/base/store/v1beta1/commit_info.proto +++ b/proto/cosmos/base/store/v1beta1/commit_info.proto @@ -19,7 +19,7 @@ message StoreInfo { CommitID commit_id = 2 [(gogoproto.nullable) = false]; } -// CommitID defines the committment information when a specific store is +// CommitID defines the commitment information when a specific store is // committed. message CommitID { option (gogoproto.goproto_stringer) = false; diff --git a/proto/cosmos/base/tendermint/v1beta1/query.proto b/proto/cosmos/base/tendermint/v1beta1/query.proto index 3c0733ae6e46..4d513cc39123 100644 --- a/proto/cosmos/base/tendermint/v1beta1/query.proto +++ b/proto/cosmos/base/tendermint/v1beta1/query.proto @@ -189,7 +189,7 @@ message ABCIQueryResponse { } // ProofOp defines an operation used for calculating Merkle root. The data could -// be arbitrary format, providing nessecary data for example neighbouring node +// be arbitrary format, providing necessary data for example neighbouring node // hash. // // Note: This type is a duplicate of the ProofOp proto type defined in Tendermint. diff --git a/proto/cosmos/distribution/v1beta1/genesis.proto b/proto/cosmos/distribution/v1beta1/genesis.proto index 239ba42f61b0..8a6cd68397ad 100644 --- a/proto/cosmos/distribution/v1beta1/genesis.proto +++ b/proto/cosmos/distribution/v1beta1/genesis.proto @@ -31,7 +31,7 @@ message ValidatorOutstandingRewardsRecord { // validator_address is the address of the validator. string validator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // outstanding_rewards represents the oustanding rewards of a validator. + // outstanding_rewards represents the outstanding rewards of a validator. repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; } @@ -99,7 +99,7 @@ message ValidatorSlashEventRecord { // validator_address is the address of the validator. string validator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // height defines the block height at which the slash event occured. + // height defines the block height at which the slash event occurred. uint64 height = 2; // period is the period of the slash event. uint64 period = 3; diff --git a/proto/cosmos/distribution/v1beta1/query.proto b/proto/cosmos/distribution/v1beta1/query.proto index bb10d59b1a87..8ee6f1a697ea 100644 --- a/proto/cosmos/distribution/v1beta1/query.proto +++ b/proto/cosmos/distribution/v1beta1/query.proto @@ -17,7 +17,7 @@ service Query { option (google.api.http).get = "/cosmos/distribution/v1beta1/params"; } - // ValidatorDistributionInfo queries validator commision and self-delegation rewards for validator + // ValidatorDistributionInfo queries validator commission and self-delegation rewards for validator rpc ValidatorDistributionInfo(QueryValidatorDistributionInfoRequest) returns (QueryValidatorDistributionInfoResponse) { option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}"; @@ -93,7 +93,7 @@ message QueryValidatorDistributionInfoResponse { // self_bond_rewards defines the self delegations rewards. repeated cosmos.base.v1beta1.DecCoin self_bond_rewards = 2 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; - // commission defines the commision the validator received. + // commission defines the commission the validator received. repeated cosmos.base.v1beta1.DecCoin commission = 3 [ (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false @@ -123,7 +123,7 @@ message QueryValidatorCommissionRequest { // QueryValidatorCommissionResponse is the response type for the // Query/ValidatorCommission RPC method message QueryValidatorCommissionResponse { - // commission defines the commision the validator received. + // commission defines the commission the validator received. ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false]; } diff --git a/proto/cosmos/gov/v1beta1/genesis.proto b/proto/cosmos/gov/v1beta1/genesis.proto index be9b07e46726..28cdacb36998 100644 --- a/proto/cosmos/gov/v1beta1/genesis.proto +++ b/proto/cosmos/gov/v1beta1/genesis.proto @@ -17,10 +17,10 @@ message GenesisState { repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; // proposals defines all the proposals present at genesis. repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; - // params defines all the paramaters of related to deposit. + // params defines all the parameters of related to deposit. DepositParams deposit_params = 5 [(gogoproto.nullable) = false]; - // params defines all the paramaters of related to voting. + // params defines all the parameters of related to voting. VotingParams voting_params = 6 [(gogoproto.nullable) = false]; - // params defines all the paramaters of related to tally. + // params defines all the parameters of related to tally. TallyParams tally_params = 7 [(gogoproto.nullable) = false]; } diff --git a/proto/cosmos/group/v1/types.proto b/proto/cosmos/group/v1/types.proto index 837271542c63..43170be86a11 100644 --- a/proto/cosmos/group/v1/types.proto +++ b/proto/cosmos/group/v1/types.proto @@ -223,7 +223,7 @@ message Proposal { TallyResult final_tally_result = 9 [(gogoproto.nullable) = false]; // voting_period_end is the timestamp before which voting must be done. - // Unless a successfull MsgExec is called before (to execute a proposal whose + // Unless a successful MsgExec is called before (to execute a proposal whose // tally is successful before the voting period ends), tallying will be done // at this point, and the `final_tally_result`and `status` fields will be // accordingly updated. diff --git a/proto/tendermint/crypto/proof.proto b/proto/tendermint/crypto/proof.proto index 975df7685397..7293ae63ee58 100644 --- a/proto/tendermint/crypto/proof.proto +++ b/proto/tendermint/crypto/proof.proto @@ -27,7 +27,7 @@ message DominoOp { } // ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data +// The data could be arbitrary format, providing necessary data // for example neighbouring node hash message ProofOp { string type = 1; diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index bc6cfd468f7b..dc55cd1fb24e 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash -mockgen_cmd="go run github.com/golang/mock/mockgen" +mockgen_cmd="mockgen" $mockgen_cmd -source=client/account_retriever.go -package mock -destination testutil/mock/account_retriever.go $mockgen_cmd -package mock -destination testutil/mock/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB -$mockgen_cmd -source db/types.go -package mock -destination testutil/mock/db/types.go $mockgen_cmd -source=types/module/module.go -package mock -destination testutil/mock/types_module_module.go $mockgen_cmd -source=types/invariant.go -package mock -destination testutil/mock/types_invariant.go $mockgen_cmd -source=types/router.go -package mock -destination testutil/mock/types_router.go diff --git a/server/start.go b/server/start.go index beb51729b686..1cee1089d130 100644 --- a/server/start.go +++ b/server/start.go @@ -417,13 +417,18 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App if err != nil { return err } - + defer grpcSrv.Stop() if config.GRPCWeb.Enable { grpcWebSrv, err = servergrpc.StartGRPCWeb(grpcSrv, config) if err != nil { ctx.Logger.Error("failed to start grpc-web http server: ", err) return err } + defer func() { + if err := grpcWebSrv.Close(); err != nil { + ctx.Logger.Error("failed to close grpc-web http server: ", err) + } + }() } } @@ -486,7 +491,7 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App } defer func() { - if tmNode.IsRunning() { + if tmNode != nil && tmNode.IsRunning() { _ = tmNode.Stop() } @@ -498,15 +503,6 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App _ = apiSrv.Close() } - if grpcSrv != nil { - grpcSrv.Stop() - if grpcWebSrv != nil { - if err := grpcWebSrv.Close(); err != nil { - ctx.Logger.Error("failed to close grpc-web http server: ", err) - } - } - } - ctx.Logger.Info("exiting...") }() diff --git a/simapp/app.go b/simapp/app.go index e6e3d3a87482..2784de096a2d 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -89,9 +89,6 @@ import ( ) var ( - // App is deprecated, use runtime.AppI instead - App runtime.AppI - // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string diff --git a/simapp/app_legacy.go b/simapp/app_legacy.go index ba664d41f225..4fa8ca9ce863 100644 --- a/simapp/app_legacy.go +++ b/simapp/app_legacy.go @@ -100,9 +100,6 @@ import ( const appName = "SimApp" var ( - // App is deprecated, use runtime.AppI instead - App runtime.AppI - // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string diff --git a/simapp/go.mod b/simapp/go.mod index 78765cdd4e5d..d80103332baf 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/simapp -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index ef43924b10d1..be559a51ea40 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -13,13 +13,18 @@ import ( simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" ) // Profile with: // /usr/local/go/bin/go test -benchmem -run=^$ cosmossdk.io/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out func BenchmarkFullAppSimulation(b *testing.B) { b.ReportAllocs() - config, db, dir, logger, skip, err := SetupSimulation("goleveldb-app-sim", "Simulation") + + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "goleveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if err != nil { b.Fatalf("simulation setup failed: %s", err.Error()) } @@ -35,7 +40,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue app := NewSimApp(logger, db, nil, true, appOptions, interBlockCacheOpt()) @@ -46,14 +51,14 @@ func BenchmarkFullAppSimulation(b *testing.B) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - if err = CheckExportSimulation(app, config, simParams); err != nil { + if err = simtestutil.CheckExportSimulation(app, config, simParams); err != nil { b.Fatal(err) } @@ -62,13 +67,17 @@ func BenchmarkFullAppSimulation(b *testing.B) { } if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } } func BenchmarkInvariants(b *testing.B) { b.ReportAllocs() - config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-invariant-bench", "Simulation") + + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-invariant-bench", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if err != nil { b.Fatalf("simulation setup failed: %s", err.Error()) } @@ -86,7 +95,7 @@ func BenchmarkInvariants(b *testing.B) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue app := NewSimApp(logger, db, nil, true, appOptions, interBlockCacheOpt()) @@ -97,14 +106,14 @@ func BenchmarkInvariants(b *testing.B) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - if err = CheckExportSimulation(app, config, simParams); err != nil { + if err = simtestutil.CheckExportSimulation(app, config, simParams); err != nil { b.Fatal(err) } @@ -113,7 +122,7 @@ func BenchmarkInvariants(b *testing.B) { } if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight() + 1}) diff --git a/simapp/sim_test.go b/simapp/sim_test.go index ed96329cbace..bfa4bd2d352e 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -34,13 +34,17 @@ import ( minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/simulation" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) +// SimAppChainID hardcoded chainID for simulation +const SimAppChainID = "simulation-app" + // Get flags every time the simulator is run func init() { - GetSimulatorFlags() + simcli.GetSimulatorFlags() } type StoreKeysPrefixes struct { @@ -62,7 +66,10 @@ func interBlockCacheOpt() func(*baseapp.BaseApp) { } func TestFullAppSimulation(t *testing.T) { - config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if skip { t.Skip("skipping application simulation") } @@ -75,7 +82,7 @@ func TestFullAppSimulation(t *testing.T) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) @@ -87,24 +94,27 @@ func TestFullAppSimulation(t *testing.T) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - err = CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(app, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } } func TestAppImportExport(t *testing.T) { - config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if skip { t.Skip("skipping application import/export simulation") } @@ -117,7 +127,7 @@ func TestAppImportExport(t *testing.T) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) @@ -129,19 +139,19 @@ func TestAppImportExport(t *testing.T) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - err = CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(app, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } fmt.Printf("exporting genesis...\n") @@ -151,7 +161,7 @@ func TestAppImportExport(t *testing.T) { fmt.Printf("importing genesis...\n") - _, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2") + newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) require.NoError(t, err, "simulation setup failed") defer func() { @@ -212,12 +222,15 @@ func TestAppImportExport(t *testing.T) { require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare") fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B) - require.Equal(t, 0, len(failedKVAs), GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + require.Equal(t, 0, len(failedKVAs), simtestutil.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) } } func TestAppSimulationAfterImport(t *testing.T) { - config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if skip { t.Skip("skipping application simulation after import") } @@ -230,7 +243,7 @@ func TestAppSimulationAfterImport(t *testing.T) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) @@ -242,19 +255,19 @@ func TestAppSimulationAfterImport(t *testing.T) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - err = CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(app, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } if stopEarly { @@ -269,7 +282,7 @@ func TestAppSimulationAfterImport(t *testing.T) { fmt.Printf("importing genesis...\n") - _, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2") + newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) require.NoError(t, err, "simulation setup failed") defer func() { @@ -290,7 +303,7 @@ func TestAppSimulationAfterImport(t *testing.T) { newApp.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(newApp, newApp.AppCodec(), config), + simtestutil.SimulationOperations(newApp, newApp.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), @@ -301,16 +314,16 @@ func TestAppSimulationAfterImport(t *testing.T) { // TODO: Make another test for the fuzzer itself, which just has noOp txs // and doesn't depend on the application. func TestAppStateDeterminism(t *testing.T) { - if !FlagEnabledValue { + if !simcli.FlagEnabledValue { t.Skip("skipping application simulation") } - config := NewConfigFromFlags() + config := simcli.NewConfigFromFlags() config.InitialBlockHeight = 1 config.ExportParamsPath = "" config.OnOperation = false config.AllInvariants = false - config.ChainID = simtestutil.SimAppChainID + config.ChainID = SimAppChainID numSeeds := 3 numTimesToRunPerSeed := 5 @@ -318,14 +331,14 @@ func TestAppStateDeterminism(t *testing.T) { appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = DefaultNodeHome - appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue for i := 0; i < numSeeds; i++ { config.Seed = rand.Int63() for j := 0; j < numTimesToRunPerSeed; j++ { var logger log.Logger - if FlagVerboseValue { + if simcli.FlagVerboseValue { logger = log.TestingLogger() } else { logger = log.NewNopLogger() @@ -345,7 +358,7 @@ func TestAppStateDeterminism(t *testing.T) { app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), ModuleAccountAddrs(), config, app.AppCodec(), @@ -353,7 +366,7 @@ func TestAppStateDeterminism(t *testing.T) { require.NoError(t, err) if config.Commit { - PrintStats(db) + simtestutil.PrintStats(db) } appHash := app.LastCommitID().Hash diff --git a/simapp/state.go b/simapp/state.go index 0fb2a333d36a..29b3259ffe78 100644 --- a/simapp/state.go +++ b/simapp/state.go @@ -20,6 +20,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -29,10 +30,10 @@ import ( func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simtypes.AppStateFn { return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config, ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { - if FlagGenesisTimeValue == 0 { + if simcli.FlagGenesisTimeValue == 0 { genesisTimestamp = simtypes.RandTimestamp(r) } else { - genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0) + genesisTimestamp = time.Unix(simcli.FlagGenesisTimeValue, 0) } chainID = config.ChainID @@ -44,7 +45,7 @@ func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simty // override the default chain-id from simapp to set it later to the config genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) - if FlagGenesisTimeValue == 0 { + if simcli.FlagGenesisTimeValue == 0 { // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) genesisTimestamp = genesisDoc.GenesisTime } diff --git a/snapshots/helpers_test.go b/snapshots/helpers_test.go index 5a9e44daf660..449b9573909c 100644 --- a/snapshots/helpers_test.go +++ b/snapshots/helpers_test.go @@ -90,7 +90,6 @@ func snapshotItems(items [][]byte, ext snapshottypes.ExtensionSnapshotter) [][]b return snapshottypes.WriteExtensionPayload(protoWriter, payload) }) _ = protoWriter.Close() - _ = zWriter.Close() _ = bufWriter.Flush() _ = chunkWriter.Close() }() diff --git a/snapshots/manager_test.go b/snapshots/manager_test.go index 58a302e87ca8..ee4c3b471189 100644 --- a/snapshots/manager_test.go +++ b/snapshots/manager_test.go @@ -95,7 +95,7 @@ func TestManager_Take(t *testing.T) { Height: 5, Format: snapshotter.SnapshotFormat(), Chunks: 1, - Hash: []uint8{0x89, 0xfa, 0x18, 0xbc, 0x5a, 0xe3, 0xdc, 0x36, 0xa6, 0x95, 0x5, 0x17, 0xf9, 0x2, 0x1a, 0x55, 0x36, 0x16, 0x5d, 0x4b, 0x8b, 0x2b, 0x3d, 0xfd, 0xe, 0x2f, 0xb6, 0x40, 0x6b, 0xc3, 0xbc, 0x23}, + Hash: []uint8{0xc5, 0xf7, 0xfe, 0xea, 0xd3, 0x4d, 0x3e, 0x87, 0xff, 0x41, 0xa2, 0x27, 0xfa, 0xcb, 0x38, 0x17, 0xa, 0x5, 0xeb, 0x27, 0x4e, 0x16, 0x5e, 0xf3, 0xb2, 0x8b, 0x47, 0xd1, 0xe6, 0x94, 0x7e, 0x8b}, Metadata: types.Metadata{ ChunkHashes: checksums(expectChunks), }, diff --git a/snapshots/stream.go b/snapshots/stream.go index 88bef076812f..fa61e1457f44 100644 --- a/snapshots/stream.go +++ b/snapshots/stream.go @@ -57,10 +57,6 @@ func (sw *StreamWriter) Close() error { sw.chunkWriter.CloseWithError(err) return err } - if err := sw.zWriter.Close(); err != nil { - sw.chunkWriter.CloseWithError(err) - return err - } if err := sw.bufWriter.Flush(); err != nil { sw.chunkWriter.CloseWithError(err) return err diff --git a/snapshots/types/format.go b/snapshots/types/format.go index d5e960660ac9..317b6a6e329e 100644 --- a/snapshots/types/format.go +++ b/snapshots/types/format.go @@ -3,4 +3,4 @@ package types // CurrentFormat is the currently used format for snapshots. Snapshots using the same format // must be identical across all nodes for a given height, so this must be bumped when the binary // snapshot output changes. -const CurrentFormat uint32 = 2 +const CurrentFormat uint32 = 3 diff --git a/store/cachekv/store_test.go b/store/cachekv/store_test.go index aeb4194b34a9..f86522d5d41e 100644 --- a/store/cachekv/store_test.go +++ b/store/cachekv/store_test.go @@ -152,6 +152,59 @@ func TestCacheKVIteratorBounds(t *testing.T) { require.Equal(t, 4, i) } +func TestCacheKVReverseIteratorBounds(t *testing.T) { + st := newCacheKVStore() + + // set some items + nItems := 5 + for i := 0; i < nItems; i++ { + st.Set(keyFmt(i), valFmt(i)) + } + + // iterate over all of them + itr := st.ReverseIterator(nil, nil) + i := 0 + for ; itr.Valid(); itr.Next() { + k, v := itr.Key(), itr.Value() + require.Equal(t, keyFmt(nItems-1-i), k) + require.Equal(t, valFmt(nItems-1-i), v) + i++ + } + require.Equal(t, nItems, i) + + // iterate over none + itr = st.ReverseIterator(bz("money"), nil) + i = 0 + for ; itr.Valid(); itr.Next() { + i++ + } + require.Equal(t, 0, i) + + // iterate over lower + end := 3 + itr = st.ReverseIterator(keyFmt(0), keyFmt(end)) + i = 0 + for ; itr.Valid(); itr.Next() { + i++ + k, v := itr.Key(), itr.Value() + require.Equal(t, keyFmt(end-i), k) + require.Equal(t, valFmt(end-i), v) + } + require.Equal(t, 3, i) + + // iterate over upper + end = 4 + itr = st.ReverseIterator(keyFmt(2), keyFmt(end)) + i = 0 + for ; itr.Valid(); itr.Next() { + i++ + k, v := itr.Key(), itr.Value() + require.Equal(t, keyFmt(end-i), k) + require.Equal(t, valFmt(end-i), v) + } + require.Equal(t, 2, i) +} + func TestCacheKVMergeIteratorBasics(t *testing.T) { st := newCacheKVStore() @@ -291,6 +344,21 @@ func TestCacheKVMergeIteratorChunks(t *testing.T) { assertIterateDomainCheck(t, st, truth, []keyRange{{0, 15}, {25, 35}, {38, 40}, {45, 80}}) } +func TestCacheKVMergeIteratorDomain(t *testing.T) { + st := newCacheKVStore() + + start, end := st.Iterator(nil, nil).Domain() + require.Equal(t, start, end) + + start, end = st.Iterator(keyFmt(40), keyFmt(60)).Domain() + require.Equal(t, keyFmt(40), start) + require.Equal(t, keyFmt(60), end) + + start, end = st.ReverseIterator(keyFmt(0), keyFmt(80)).Domain() + require.Equal(t, keyFmt(0), start) + require.Equal(t, keyFmt(80), end) +} + func TestCacheKVMergeIteratorRandom(t *testing.T) { st := newCacheKVStore() truth := dbm.NewMemDB() diff --git a/store/rootmulti/snapshot_test.go b/store/rootmulti/snapshot_test.go index bad1603da7c9..de7880788eee 100644 --- a/store/rootmulti/snapshot_test.go +++ b/store/rootmulti/snapshot_test.go @@ -128,7 +128,7 @@ func TestMultistoreSnapshot_Checksum(t *testing.T) { "aa048b4ee0f484965d7b3b06822cf0772cdcaad02f3b1b9055e69f2cb365ef3c", "7921eaa3ed4921341e504d9308a9877986a879fe216a099c86e8db66fcba4c63", "a4a864e6c02c9fca5837ec80dc84f650b25276ed7e4820cf7516ced9f9901b86", - "ca2879ac6e7205d257440131ba7e72bef784cd61642e32b847729e543c1928b9", + "980925390cc50f14998ecb1e87de719ca9dd7e72f5fefbe445397bf670f36c31", }}, } for _, tc := range testcases { diff --git a/store/tools/ics23/go.mod b/store/tools/ics23/go.mod index 88bf8aac9b95..b59e7aa365c7 100644 --- a/store/tools/ics23/go.mod +++ b/store/tools/ics23/go.mod @@ -1,6 +1,6 @@ module github.com/cosmos/cosmos-sdk/store/tools/ics23 -go 1.18 +go 1.19 require ( github.com/confio/ics23/go v0.7.0 diff --git a/store/tools/ics23/iavl/helpers/helpers.go b/store/tools/ics23/iavl/helpers/helpers.go index d552166a25b8..4f41600b65ea 100644 --- a/store/tools/ics23/iavl/helpers/helpers.go +++ b/store/tools/ics23/iavl/helpers/helpers.go @@ -88,6 +88,9 @@ func GetNonKey(allkeys [][]byte, loc tmproofs.Where) []byte { // returns a list of all keys in sorted order func BuildTree(size int) (tree *iavl.MutableTree, keys [][]byte, err error) { tree, err = iavl.NewMutableTree(db.NewMemDB(), 0) + if err != nil { + return nil, nil, err + } // insert lots of info and store the bytes keys = make([][]byte, size) diff --git a/tests/e2e/bank/client/grpc.go b/tests/e2e/bank/client/grpc.go index 15814414f041..712d589ac27c 100644 --- a/tests/e2e/bank/client/grpc.go +++ b/tests/e2e/bank/client/grpc.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/rest" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/types/query" @@ -277,7 +276,7 @@ func (s *EndToEndTestSuite) TestBalancesGRPCHandler() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) diff --git a/tests/e2e/client/grpc/tmservice/service_test.go b/tests/e2e/client/grpc/tmservice/service_test.go index 34ca8a1b1280..a0cba3edb417 100644 --- a/tests/e2e/client/grpc/tmservice/service_test.go +++ b/tests/e2e/client/grpc/tmservice/service_test.go @@ -13,9 +13,9 @@ import ( "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/configurator" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/testutil/rest" "github.com/cosmos/cosmos-sdk/types" qtypes "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/version" @@ -72,7 +72,7 @@ func (s *IntegrationTestSuite) TestQueryNodeInfo() { s.Require().NoError(err) s.Require().Equal(res.ApplicationVersion.AppName, version.NewInfo().AppName) - restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.APIAddress)) + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.APIAddress)) s.Require().NoError(err) var getInfoRes tmservice.GetNodeInfoResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &getInfoRes)) @@ -85,7 +85,7 @@ func (s *IntegrationTestSuite) TestQuerySyncing() { _, err := s.queryClient.GetSyncing(context.Background(), &tmservice.GetSyncingRequest{}) s.Require().NoError(err) - restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.APIAddress)) + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.APIAddress)) s.Require().NoError(err) var syncingRes tmservice.GetSyncingResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &syncingRes)) @@ -97,7 +97,7 @@ func (s *IntegrationTestSuite) TestQueryLatestBlock() { _, err := s.queryClient.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{}) s.Require().NoError(err) - restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.APIAddress)) + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.APIAddress)) s.Require().NoError(err) var blockInfoRes tmservice.GetLatestBlockResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &blockInfoRes)) @@ -110,7 +110,7 @@ func (s *IntegrationTestSuite) TestQueryBlockByHeight() { _, err := s.queryClient.GetBlockByHeight(context.Background(), &tmservice.GetBlockByHeightRequest{Height: 1}) s.Require().NoError(err) - restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.APIAddress, 1)) + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.APIAddress, 1)) s.Require().NoError(err) var blockInfoRes tmservice.GetBlockByHeightResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &blockInfoRes)) @@ -138,11 +138,11 @@ func (s *IntegrationTestSuite) TestQueryLatestValidatorSet() { s.Require().NoError(err) // rest request without pagination - _, err = rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", val.APIAddress)) + _, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", val.APIAddress)) s.Require().NoError(err) // rest request with pagination - restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 0, 1)) + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 0, 1)) s.Require().NoError(err) var validatorSetRes tmservice.GetLatestValidatorSetResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &validatorSetRes)) @@ -198,7 +198,7 @@ func (s *IntegrationTestSuite) TestLatestValidatorSet_GRPCGateway() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - res, err := rest.GetRequest(tc.url) + res, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) @@ -260,7 +260,7 @@ func (s *IntegrationTestSuite) TestValidatorSetByHeight_GRPCGateway() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - res, err := rest.GetRequest(tc.url) + res, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) diff --git a/tests/e2e/group/tx.go b/tests/e2e/group/tx.go index 7488806c798e..c50ef6f0fc3d 100644 --- a/tests/e2e/group/tx.go +++ b/tests/e2e/group/tx.go @@ -2151,6 +2151,8 @@ func (s *IntegrationTestSuite) TestTxLeaveGroup() { ), ) s.Require().NoError(err, out.String()) + s.Require().NoError(s.network.WaitForNextBlock()) + var txResp sdk.TxResponse s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) txResp, err = clitestutil.GetTxResponse(s.network, val.ClientCtx, txResp.TxHash) diff --git a/tests/e2e/nft/grpc.go b/tests/e2e/nft/grpc.go index 718793f0b8d0..6b6d84943fc4 100644 --- a/tests/e2e/nft/grpc.go +++ b/tests/e2e/nft/grpc.go @@ -3,7 +3,7 @@ package nft import ( "fmt" - "github.com/cosmos/cosmos-sdk/testutil/rest" + "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/x/nft" ) @@ -61,7 +61,7 @@ func (s *IntegrationTestSuite) TestQueryBalanceGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(balanceURL, tc.args.Owner, tc.args.ClassID) s.Run(tc.name, func() { - resp, _ := rest.GetRequest(uri) + resp, _ := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errMsg) } else { @@ -153,7 +153,7 @@ func (s *IntegrationTestSuite) TestQueryOwnerGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(ownerURL, tc.args.ClassID, tc.args.ID) s.Run(tc.name, func() { - resp, err := rest.GetRequest(uri) + resp, err := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errMsg) } else { @@ -215,7 +215,7 @@ func (s *IntegrationTestSuite) TestQuerySupplyGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(supplyURL, tc.args.ClassID) s.Run(tc.name, func() { - resp, err := rest.GetRequest(uri) + resp, err := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errMsg) } else { @@ -312,7 +312,7 @@ func (s *IntegrationTestSuite) TestQueryNFTsGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(nftsOfClassURL, tc.args.ClassID, tc.args.Owner) s.Run(tc.name, func() { - resp, err := rest.GetRequest(uri) + resp, err := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errorMsg) } else { @@ -401,7 +401,7 @@ func (s *IntegrationTestSuite) TestQueryNFTGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(nftURL, tc.args.ClassID, tc.args.ID) s.Run(tc.name, func() { - resp, err := rest.GetRequest(uri) + resp, err := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errorMsg) } else { @@ -449,7 +449,7 @@ func (s *IntegrationTestSuite) TestQueryClassGRPC() { for _, tc := range testCases { uri := fmt.Sprintf(classURL, tc.args.ClassID) s.Run(tc.name, func() { - resp, err := rest.GetRequest(uri) + resp, err := testutil.GetRequest(uri) if tc.expectErr { s.Require().Contains(string(resp), tc.errorMsg) } else { @@ -466,7 +466,7 @@ func (s *IntegrationTestSuite) TestQueryClassGRPC() { func (s *IntegrationTestSuite) TestQueryClassesGRPC() { val := s.network.Validators[0] classURL := val.APIAddress + "/cosmos/nft/v1beta1/classes" - resp, err := rest.GetRequest(classURL) + resp, err := testutil.GetRequest(classURL) s.Require().NoError(err) var result nft.QueryClassesResponse err = val.ClientCtx.Codec.UnmarshalJSON(resp, &result) diff --git a/tests/e2e/staking/client/testutil/grpc.go b/tests/e2e/staking/client/testutil/grpc.go index 47378d51e7e1..d5673a8ff600 100644 --- a/tests/e2e/staking/client/testutil/grpc.go +++ b/tests/e2e/staking/client/testutil/grpc.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/rest" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/types/query" @@ -46,7 +45,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryValidatorsHandler() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var valRes types.QueryValidatorsResponse @@ -94,7 +93,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryValidator() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var validator types.QueryValidatorResponse @@ -203,7 +202,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryValidatorUnbondingDelegations() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var ubds types.QueryValidatorUnbondingDelegationsResponse @@ -282,7 +281,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryDelegation() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) s.T().Logf("%s", resp) err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType) @@ -336,7 +335,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryUnbondingDelegation() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var ubd types.QueryUnbondingDelegationResponse @@ -470,7 +469,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var ubds types.QueryDelegatorUnbondingDelegationsResponse @@ -532,7 +531,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryRedelegations() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var redelegations types.QueryRedelegationsResponse @@ -581,7 +580,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryDelegatorValidators() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var validators types.QueryDelegatorValidatorsResponse @@ -638,7 +637,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryDelegatorValidator() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var validator types.QueryDelegatorValidatorResponse @@ -684,7 +683,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryHistoricalInfo() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var historicalInfo types.QueryHistoricalInfoResponse @@ -723,7 +722,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryParams() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Run(tc.name, func() { s.Require().NoError(err) s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) diff --git a/tests/e2e/staking/client/testutil/suite.go b/tests/e2e/staking/client/testutil/suite.go index f4ecf45c0688..c49723943e99 100644 --- a/tests/e2e/staking/client/testutil/suite.go +++ b/tests/e2e/staking/client/testutil/suite.go @@ -17,9 +17,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/testutil/rest" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" @@ -1406,7 +1406,7 @@ func (s *IntegrationTestSuite) TestNewCancelUnbondingDelegationCmd() { if !tc.expectErr && tc.expectedCode != sdkerrors.ErrNotFound.ABCICode() { getCreationHeight := func() int64 { // fethichg the unbonding delegations - resp, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", val.APIAddress, val.Address.String())) + resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", val.APIAddress, val.Address.String())) s.Require().NoError(err) var ubds types.QueryDelegatorUnbondingDelegationsResponse diff --git a/tests/e2e/tx/service_test.go b/tests/e2e/tx/service_test.go index 881804e99e50..1b3896c0b4b8 100644 --- a/tests/e2e/tx/service_test.go +++ b/tests/e2e/tx/service_test.go @@ -21,7 +21,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/testutil/rest" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -259,7 +258,7 @@ func (s IntegrationTestSuite) TestSimulateTx_GRPCGateway() { s.Run(tc.name, func() { req, err := val.ClientCtx.Codec.MarshalJSON(tc.req) s.Require().NoError(err) - res, err := rest.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", val.APIAddress), "application/json", req) + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", val.APIAddress), "application/json", req) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) @@ -413,7 +412,7 @@ func (s IntegrationTestSuite) TestGetTxEvents_GRPCGateway() { } for _, tc := range testCases { s.Run(tc.name, func() { - res, err := rest.GetRequest(tc.url) + res, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) @@ -483,7 +482,7 @@ func (s IntegrationTestSuite) TestGetTx_GRPCGateway() { } for _, tc := range testCases { s.Run(tc.name, func() { - res, err := rest.GetRequest(tc.url) + res, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) @@ -566,7 +565,7 @@ func (s IntegrationTestSuite) TestBroadcastTx_GRPCGateway() { s.Run(tc.name, func() { req, err := val.ClientCtx.Codec.MarshalJSON(tc.req) s.Require().NoError(err) - res, err := rest.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress), "application/json", req) + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress), "application/json", req) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) @@ -751,7 +750,7 @@ func (s IntegrationTestSuite) TestGetBlockWithTxs_GRPCGateway() { } for _, tc := range testCases { s.Run(tc.name, func() { - res, err := rest.GetRequest(tc.url) + res, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expErr { s.Require().Contains(string(res), tc.expErrMsg) diff --git a/tests/go.mod b/tests/go.mod index cff43930a63f..1796abb2164a 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -1,6 +1,6 @@ module github.com/cosmos/cosmos-sdk/tests -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/testutil/rest.go b/testutil/rest.go index 58e6c39b197e..b3c52e3adbc3 100644 --- a/testutil/rest.go +++ b/testutil/rest.go @@ -1,6 +1,8 @@ package testutil import ( + "bytes" + "fmt" "io" "net/http" ) @@ -36,3 +38,41 @@ func GetRequestWithHeaders(url string, headers map[string]string) ([]byte, error return body, nil } + +// GetRequest defines a wrapper around an HTTP GET request with a provided URL. +// An error is returned if the request or reading the body fails. +func GetRequest(url string) ([]byte, error) { + res, err := http.Get(url) //nolint:gosec + if err != nil { + return nil, err + } + defer func() { + _ = res.Body.Close() + }() + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + return body, nil +} + +// PostRequest defines a wrapper around an HTTP POST request with a provided URL and data. +// An error is returned if the request or reading the body fails. +func PostRequest(url string, contentType string, data []byte) ([]byte, error) { + res, err := http.Post(url, contentType, bytes.NewBuffer(data)) //nolint:gosec + if err != nil { + return nil, fmt.Errorf("error while sending post request: %w", err) + } + defer func() { + _ = res.Body.Close() + }() + + bz, err := io.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + + return bz, nil +} diff --git a/testutil/rest/rest.go b/testutil/rest/rest.go deleted file mode 100644 index 89a16b3ff286..000000000000 --- a/testutil/rest/rest.go +++ /dev/null @@ -1,48 +0,0 @@ -// Package rest provides HTTP types and primitives for REST -// requests validation and responses handling. -package rest - -import ( - "bytes" - "fmt" - "io" - "net/http" -) - -// GetRequest defines a wrapper around an HTTP GET request with a provided URL. -// An error is returned if the request or reading the body fails. -func GetRequest(url string) ([]byte, error) { - res, err := http.Get(url) //nolint:gosec - if err != nil { - return nil, err - } - defer func() { - _ = res.Body.Close() - }() - - body, err := io.ReadAll(res.Body) - if err != nil { - return nil, err - } - - return body, nil -} - -// PostRequest defines a wrapper around an HTTP POST request with a provided URL and data. -// An error is returned if the request or reading the body fails. -func PostRequest(url string, contentType string, data []byte) ([]byte, error) { - res, err := http.Post(url, contentType, bytes.NewBuffer(data)) //nolint:gosec - if err != nil { - return nil, fmt.Errorf("error while sending post request: %w", err) - } - defer func() { - _ = res.Body.Close() - }() - - bz, err := io.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - - return bz, nil -} diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index 08aa4597e15a..ff5d22a954da 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -29,11 +29,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// SimAppChainID hardcoded chainID for simulation -const ( - DefaultGenTxGas = 10000000 - SimAppChainID = "simulation-app" -) +const DefaultGenTxGas = 10000000 // DefaultConsensusParams defines the default Tendermint consensus params used in // SimApp testing. diff --git a/simapp/utils.go b/testutil/sims/simulation_helpers.go similarity index 81% rename from simapp/utils.go rename to testutil/sims/simulation_helpers.go index 4c2e7de0f470..420171b05ceb 100644 --- a/simapp/utils.go +++ b/testutil/sims/simulation_helpers.go @@ -1,35 +1,30 @@ -package simapp +package sims import ( "encoding/json" "fmt" "os" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/tendermint/tendermint/libs/log" + dbm "github.com/tendermint/tm-db" ) -// SetupSimulation creates the config, db (levelDB), temporary directory and logger for -// the simulation tests. If `FlagEnabledValue` is false it skips the current test. +// SetupSimulation creates the config, db (levelDB), temporary directory and logger for the simulation tests. +// If `skip` is false it skips the current test. `skip` should be set using the `FlagEnabledValue` flag. // Returns error on an invalid db intantiation or temp dir creation. -func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { - if !FlagEnabledValue { - return simtypes.Config{}, nil, "", nil, true, nil +func SetupSimulation(config simtypes.Config, dirPrefix, dbName string, verbose, skip bool) (dbm.DB, string, log.Logger, bool, error) { + if !skip { + return nil, "", nil, true, nil } - config := NewConfigFromFlags() - config.ChainID = simtestutil.SimAppChainID - var logger log.Logger - if FlagVerboseValue { + if verbose { logger = log.TestingLogger() } else { logger = log.NewNopLogger() @@ -37,15 +32,15 @@ func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, dir, err := os.MkdirTemp("", dirPrefix) if err != nil { - return simtypes.Config{}, nil, "", nil, false, err + return nil, "", nil, false, err } db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir) if err != nil { - return simtypes.Config{}, nil, "", nil, false, err + return nil, "", nil, false, err } - return config, db, dir, logger, false, nil + return db, dir, logger, false, nil } // SimulationOperations retrieves the simulation params from the provided file path @@ -74,9 +69,7 @@ func SimulationOperations(app runtime.AppI, cdc codec.JSONCodec, config simtypes // CheckExportSimulation exports the app state and simulation parameters to JSON // if the export paths are defined. -func CheckExportSimulation( - app runtime.AppI, config simtypes.Config, params simtypes.Params, -) error { +func CheckExportSimulation(app runtime.AppI, config simtypes.Config, params simtypes.Params) error { if config.ExportStatePath != "" { fmt.Println("exporting app state...") exported, err := app.ExportAppStateAndValidators(false, nil) diff --git a/simapp/utils_test.go b/testutil/sims/simulation_helpers_test.go similarity index 71% rename from simapp/utils_test.go rename to testutil/sims/simulation_helpers_test.go index 0240c482a558..793fb9947a8d 100644 --- a/simapp/utils_test.go +++ b/testutil/sims/simulation_helpers_test.go @@ -1,4 +1,4 @@ -package simapp +package sims import ( "fmt" @@ -7,25 +7,13 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/std" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" - "github.com/cosmos/cosmos-sdk/types/module" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) -func makeCodec(bm module.BasicManager) *codec.LegacyAmino { - cdc := codec.NewLegacyAmino() - - bm.RegisterLegacyAminoCodec(cdc) - std.RegisterLegacyAminoCodec(cdc) - - return cdc -} - func TestGetSimulationLog(t *testing.T) { - cdc := makeCodec(ModuleBasics) - + legacyAmino := codec.NewLegacyAmino() decoders := make(sdk.StoreDecoderRegistry) decoders[authtypes.StoreKey] = func(kvAs, kvBs kv.Pair) string { return "10" } @@ -41,7 +29,7 @@ func TestGetSimulationLog(t *testing.T) { }, { authtypes.StoreKey, - []kv.Pair{{Key: authtypes.GlobalAccountNumberKey, Value: cdc.MustMarshal(uint64(10))}}, + []kv.Pair{{Key: authtypes.GlobalAccountNumberKey, Value: legacyAmino.MustMarshal(uint64(10))}}, "10", }, { diff --git a/tx/go.mod b/tx/go.mod index 5a56dde79530..30a868f67611 100644 --- a/tx/go.mod +++ b/tx/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/tx -go 1.18 +go 1.19 require ( cosmossdk.io/api v0.2.1 diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index 3c9dd000106c..6ddde70a30f6 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -139,9 +139,9 @@ func GetAccountAddressByIDCmd() *cobra.Command { return err } - id, err := strconv.ParseInt(args[0], 10, 64) + id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return err + return fmt.Errorf("id %s not a valid uint, please input a valid account-id", args[0]) } queryClient := types.NewQueryClient(clientCtx) diff --git a/x/auth/client/cli/tx_sign.go b/x/auth/client/cli/tx_sign.go index f6870c5eb3b4..ebc2ffc4adb3 100644 --- a/x/auth/client/cli/tx_sign.go +++ b/x/auth/client/cli/tx_sign.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" + sdk "github.com/cosmos/cosmos-sdk/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" ) @@ -20,6 +21,7 @@ const ( flagSigOnly = "signature-only" flagAmino = "amino" flagNoAutoIncrement = "no-auto-increment" + flagAppend = "append" ) // GetSignBatchCommand returns the transaction sign-batch command. @@ -53,7 +55,9 @@ account key. It implies --signature-only. cmd.Flags().String(flagMultisig, "", "Address or key name of the multisig account on behalf of which the transaction shall be signed") cmd.Flags().String(flags.FlagOutputDocument, "", "The document will be written to the given file instead of STDOUT") - cmd.Flags().Bool(flagSigOnly, true, "Print only the generated signature, then exit") + cmd.Flags().Bool(flagSigOnly, false, "Print only the generated signature, then exit") + cmd.Flags().Bool(flagAppend, false, "Combine all message and generate single signed transaction for broadcast.") + flags.AddTxFlagsToCmd(cmd) cmd.MarkFlagRequired(flags.FlagFrom) @@ -117,13 +121,36 @@ func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error { } } - for sequence := txFactory.Sequence(); scanner.Scan(); sequence++ { - unsignedStdTx := scanner.Tx() - txFactory = txFactory.WithSequence(sequence) - txBuilder, err := txCfg.WrapTxBuilder(unsignedStdTx) - if err != nil { - return err + appendMessagesToSingleMsg, _ := cmd.Flags().GetBool(flagAppend) + if appendMessagesToSingleMsg { + // It will combine all tx msgs and create single signed transaction + txBuilder := clientCtx.TxConfig.NewTxBuilder() + msgs := make([]sdk.Msg, 0) + newGasLimit := uint64(0) + + for scanner.Scan() { + unsignedStdTx := scanner.Tx() + fe, err := clientCtx.TxConfig.WrapTxBuilder(unsignedStdTx) + if err != nil { + return err + } + // increment the gas + newGasLimit += fe.GetTx().GetGas() + // append messages + msgs = append(msgs, unsignedStdTx.GetMsgs()...) } + // set the new appened msgs into builder + txBuilder.SetMsgs(msgs...) + + // set the memo,fees,feeGranter,feePayer from cmd flags + txBuilder.SetMemo(txFactory.Memo()) + txBuilder.SetFeeAmount(txFactory.Fees()) + txBuilder.SetFeeGranter(clientCtx.FeeGranter) + txBuilder.SetFeePayer(clientCtx.FeePayer) + + // set the gasLimit + txBuilder.SetGasLimit(newGasLimit) + if ms == "" { from, _ := cmd.Flags().GetString(flags.FlagFrom) _, fromName, _, err := client.GetFromFields(clientCtx, txFactory.Keybase(), from) @@ -156,6 +183,49 @@ func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error { } cmd.Printf("%s\n", json) + + } else { + // It will generate signed tx for each tx + for sequence := txFactory.Sequence(); scanner.Scan(); sequence++ { + unsignedStdTx := scanner.Tx() + txFactory = txFactory.WithSequence(sequence) + txBuilder, err := txCfg.WrapTxBuilder(unsignedStdTx) + if err != nil { + return err + } + if ms == "" { + from, _ := cmd.Flags().GetString(flags.FlagFrom) + _, fromName, _, err := client.GetFromFields(clientCtx, txFactory.Keybase(), from) + if err != nil { + return fmt.Errorf("error getting account from keybase: %w", err) + } + err = authclient.SignTx(txFactory, clientCtx, fromName, txBuilder, true, true) + if err != nil { + return err + } + } else { + multisigAddr, _, _, err := client.GetFromFields(clientCtx, txFactory.Keybase(), ms) + if err != nil { + return fmt.Errorf("error getting account from keybase: %w", err) + } + err = authclient.SignTxWithSignerAddress( + txFactory, clientCtx, multisigAddr, clientCtx.GetFromName(), txBuilder, clientCtx.Offline, true) + if err != nil { + return err + } + } + + if err != nil { + return err + } + + json, err := marshalSignatureJSON(txCfg, txBuilder, printSignatureOnly) + if err != nil { + return err + } + + cmd.Printf("%s\n", json) + } } if err := scanner.UnmarshalErr(); err != nil { @@ -235,129 +305,139 @@ func makeSignCmd() func(cmd *cobra.Command, args []string) error { if err != nil { return err } - f := cmd.Flags() clientCtx, txF, newTx, err := readTxAndInitContexts(clientCtx, cmd, args[0]) if err != nil { return err } - txCfg := clientCtx.TxConfig - txBuilder, err := txCfg.WrapTxBuilder(newTx) + return signTx(cmd, clientCtx, txF, newTx) + } +} + +func signTx(cmd *cobra.Command, clientCtx client.Context, txF tx.Factory, newTx sdk.Tx) error { + f := cmd.Flags() + txCfg := clientCtx.TxConfig + txBuilder, err := txCfg.WrapTxBuilder(newTx) + if err != nil { + return err + } + + printSignatureOnly, err := cmd.Flags().GetBool(flagSigOnly) + if err != nil { + return err + } + + multisig, err := cmd.Flags().GetString(flagMultisig) + if err != nil { + return err + } + + from, err := cmd.Flags().GetString(flags.FlagFrom) + if err != nil { + return err + } + + _, fromName, _, err := client.GetFromFields(clientCtx, txF.Keybase(), from) + if err != nil { + return fmt.Errorf("error getting account from keybase: %w", err) + } + + overwrite, err := f.GetBool(flagOverwrite) + if err != nil { + return err + } + + if multisig != "" { + // Bech32 decode error, maybe it's a name, we try to fetch from keyring + multisigAddr, multisigName, _, err := client.GetFromFields(clientCtx, txF.Keybase(), multisig) if err != nil { - return err + return fmt.Errorf("error getting account from keybase: %w", err) } - - printSignatureOnly, _ := cmd.Flags().GetBool(flagSigOnly) - multisig, _ := cmd.Flags().GetString(flagMultisig) + multisigkey, err := getMultisigRecord(clientCtx, multisigName) if err != nil { return err } - from, _ := cmd.Flags().GetString(flags.FlagFrom) - _, fromName, _, err := client.GetFromFields(clientCtx, txF.Keybase(), from) + multisigPubKey, err := multisigkey.GetPubKey() if err != nil { - return fmt.Errorf("error getting account from keybase: %w", err) + return err } + multisigLegacyPub := multisigPubKey.(*kmultisig.LegacyAminoPubKey) - overwrite, _ := f.GetBool(flagOverwrite) - if multisig != "" { - // Bech32 decode error, maybe it's a name, we try to fetch from keyring - multisigAddr, multisigName, _, err := client.GetFromFields(clientCtx, txF.Keybase(), multisig) - if err != nil { - return fmt.Errorf("error getting account from keybase: %w", err) - } - multisigkey, err := getMultisigRecord(clientCtx, multisigName) - if err != nil { - return err - } - multisigPubKey, err := multisigkey.GetPubKey() - if err != nil { - return err - } - multisigLegacyPub := multisigPubKey.(*kmultisig.LegacyAminoPubKey) - - fromRecord, err := clientCtx.Keyring.Key(fromName) - if err != nil { - return fmt.Errorf("error getting account from keybase: %w", err) - } - fromPubKey, err := fromRecord.GetPubKey() - if err != nil { - return err - } - - var found bool - for _, pubkey := range multisigLegacyPub.GetPubKeys() { - if pubkey.Equals(fromPubKey) { - found = true - } - } - if !found { - return fmt.Errorf("signing key is not a part of multisig key") - } - err = authclient.SignTxWithSignerAddress( - txF, clientCtx, multisigAddr, fromName, txBuilder, clientCtx.Offline, overwrite) - if err != nil { - return err - } - printSignatureOnly = true - } else { - err = authclient.SignTx(txF, clientCtx, clientCtx.GetFromName(), txBuilder, clientCtx.Offline, overwrite) + fromRecord, err := clientCtx.Keyring.Key(fromName) + if err != nil { + return fmt.Errorf("error getting account from keybase: %w", err) } + fromPubKey, err := fromRecord.GetPubKey() if err != nil { return err } - aminoJSON, err := f.GetBool(flagAmino) + var found bool + for _, pubkey := range multisigLegacyPub.GetPubKeys() { + if pubkey.Equals(fromPubKey) { + found = true + } + } + if !found { + return fmt.Errorf("signing key is not a part of multisig key") + } + err = authclient.SignTxWithSignerAddress( + txF, clientCtx, multisigAddr, fromName, txBuilder, clientCtx.Offline, overwrite) if err != nil { return err } + printSignatureOnly = true + } else { + err = authclient.SignTx(txF, clientCtx, clientCtx.GetFromName(), txBuilder, clientCtx.Offline, overwrite) + } + if err != nil { + return err + } + + aminoJSON, err := f.GetBool(flagAmino) + if err != nil { + return err + } - bMode, err := f.GetString(flags.FlagBroadcastMode) + bMode, err := f.GetString(flags.FlagBroadcastMode) + if err != nil { + return err + } + + // set output + closeFunc, err := setOutputFile(cmd) + if err != nil { + return err + } + + defer closeFunc() + clientCtx.WithOutput(cmd.OutOrStdout()) + + var json []byte + if aminoJSON { + stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBuilder.GetTx()) if err != nil { return err } - - var json []byte - if aminoJSON { - stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBuilder.GetTx()) - if err != nil { - return err - } - req := BroadcastReq{ - Tx: stdTx, - Mode: bMode, - } - json, err = clientCtx.LegacyAmino.MarshalJSON(req) - if err != nil { - return err - } - } else { - json, err = marshalSignatureJSON(txCfg, txBuilder, printSignatureOnly) - if err != nil { - return err - } + req := BroadcastReq{ + Tx: stdTx, + Mode: bMode, } - - outputDoc, _ := cmd.Flags().GetString(flags.FlagOutputDocument) - if outputDoc == "" { - cmd.Printf("%s\n", json) - return nil + json, err = clientCtx.LegacyAmino.MarshalJSON(req) + if err != nil { + return err } - - fp, err := os.OpenFile(outputDoc, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644) + } else { + json, err = marshalSignatureJSON(txCfg, txBuilder, printSignatureOnly) if err != nil { return err } - defer func() { - err2 := fp.Close() - if err == nil { - err = err2 - } - }() - - _, err = fp.Write(append(json, '\n')) - return err } + + cmd.Printf("%s\n", json) + + return err } func marshalSignatureJSON(txConfig client.TxConfig, txBldr client.TxBuilder, signatureOnly bool) ([]byte, error) { diff --git a/x/auth/client/testutil/suite.go b/x/auth/client/testutil/suite.go index f262272f0df2..b4620fe4f7cc 100644 --- a/x/auth/client/testutil/suite.go +++ b/x/auth/client/testutil/suite.go @@ -1243,7 +1243,7 @@ func (s *IntegrationTestSuite) TestSignBatchMultisig() { addr1, err := account1.GetAddress() s.Require().NoError(err) // sign-batch file - res, err := TxSignBatchExec(val.ClientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String()) + res, err := TxSignBatchExec(val.ClientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), "--signature-only") s.Require().NoError(err) s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) // write sigs to file @@ -1252,7 +1252,7 @@ func (s *IntegrationTestSuite) TestSignBatchMultisig() { addr2, err := account2.GetAddress() s.Require().NoError(err) // sign-batch file with account2 - res, err = TxSignBatchExec(val.ClientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String()) + res, err = TxSignBatchExec(val.ClientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), "--signature-only") s.Require().NoError(err) s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) // write sigs to file2 @@ -1310,7 +1310,7 @@ func (s *IntegrationTestSuite) TestMultisignBatch() { // sign-batch file addr1, err := account1.GetAddress() s.Require().NoError(err) - res, err := TxSignBatchExec(val.ClientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), fmt.Sprintf("--%s", flags.FlagOffline), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, fmt.Sprint(account.GetAccountNumber())), fmt.Sprintf("--%s=%s", flags.FlagSequence, fmt.Sprint(account.GetSequence()))) + res, err := TxSignBatchExec(val.ClientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), fmt.Sprintf("--%s", flags.FlagOffline), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, fmt.Sprint(account.GetAccountNumber())), fmt.Sprintf("--%s=%s", flags.FlagSequence, fmt.Sprint(account.GetSequence())), "--signature-only") s.Require().NoError(err) s.Require().Equal(3, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) // write sigs to file @@ -1319,7 +1319,7 @@ func (s *IntegrationTestSuite) TestMultisignBatch() { // sign-batch file with account2 addr2, err := account2.GetAddress() s.Require().NoError(err) - res, err = TxSignBatchExec(val.ClientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), fmt.Sprintf("--%s", flags.FlagOffline), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, fmt.Sprint(account.GetAccountNumber())), fmt.Sprintf("--%s=%s", flags.FlagSequence, fmt.Sprint(account.GetSequence()))) + res, err = TxSignBatchExec(val.ClientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", addr.String(), fmt.Sprintf("--%s", flags.FlagOffline), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, fmt.Sprint(account.GetAccountNumber())), fmt.Sprintf("--%s=%s", flags.FlagSequence, fmt.Sprint(account.GetSequence())), "--signature-only") s.Require().NoError(err) s.Require().Equal(3, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) @@ -1587,6 +1587,7 @@ func (s *IntegrationTestSuite) TestSignWithMultiSignersAminoJSON() { ) require.NoError(err) require.NoError(s.network.WaitForNextBlock()) + require.NoError(s.network.WaitForNextBlock()) var txRes sdk.TxResponse require.NoError(val0.ClientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) diff --git a/x/auth/keeper/grpc_query.go b/x/auth/keeper/grpc_query.go index bb09dbdeac9a..2322076ddd77 100644 --- a/x/auth/keeper/grpc_query.go +++ b/x/auth/keeper/grpc_query.go @@ -24,12 +24,8 @@ func (ak AccountKeeper) AccountAddressByID(c context.Context, req *types.QueryAc return nil, status.Errorf(codes.InvalidArgument, "empty request") } - if req.Id < 0 { - return nil, status.Error(codes.InvalidArgument, "Invalid account id") - } - ctx := sdk.UnwrapSDKContext(c) - address := ak.GetAccountAddressByID(ctx, uint64(req.GetId())) + address := ak.GetAccountAddressByID(ctx, req.Id) if len(address) == 0 { return nil, status.Errorf(codes.NotFound, "account address not found with id %d", req.Id) } diff --git a/x/auth/keeper/grpc_query_test.go b/x/auth/keeper/grpc_query_test.go index 86bec2e27ef6..70594178fbdb 100644 --- a/x/auth/keeper/grpc_query_test.go +++ b/x/auth/keeper/grpc_query_test.go @@ -166,14 +166,6 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccountAddressByID() { expPass bool posttests func(res *types.QueryAccountAddressByIDResponse) }{ - { - "invalid request", - func() { - req = &types.QueryAccountAddressByIDRequest{Id: -1} - }, - false, - func(res *types.QueryAccountAddressByIDResponse) {}, - }, { "account address not found", func() { @@ -187,7 +179,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccountAddressByID() { func() { account := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) suite.accountKeeper.SetAccount(suite.ctx, account) - req = &types.QueryAccountAddressByIDRequest{Id: int64(account.GetAccountNumber())} + req = &types.QueryAccountAddressByIDRequest{Id: account.GetAccountNumber()} }, true, func(res *types.QueryAccountAddressByIDResponse) { diff --git a/x/auth/types/query.pb.go b/x/auth/types/query.pb.go index 60192dc75978..a3b43c9516a9 100644 --- a/x/auth/types/query.pb.go +++ b/x/auth/types/query.pb.go @@ -667,7 +667,7 @@ func (m *AddressStringToBytesResponse) GetAddressBytes() []byte { // QueryAccountAddressByIDRequest is the request type for AccountAddressByID rpc method type QueryAccountAddressByIDRequest struct { - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` } func (m *QueryAccountAddressByIDRequest) Reset() { *m = QueryAccountAddressByIDRequest{} } @@ -703,7 +703,7 @@ func (m *QueryAccountAddressByIDRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryAccountAddressByIDRequest proto.InternalMessageInfo -func (m *QueryAccountAddressByIDRequest) GetId() int64 { +func (m *QueryAccountAddressByIDRequest) GetId() uint64 { if m != nil { return m.Id } @@ -873,66 +873,66 @@ func init() { proto.RegisterFile("cosmos/auth/v1beta1/query.proto", fileDescript var fileDescriptor_c451370b3929a27c = []byte{ // 971 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x96, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0xbd, 0x69, 0x49, 0xc2, 0x8b, 0x1b, 0xa4, 0x89, 0x2b, 0xc2, 0x3a, 0xb5, 0xa3, 0x2d, - 0x34, 0x4e, 0xa8, 0x77, 0x1b, 0x27, 0x07, 0x0a, 0x08, 0x29, 0x6e, 0x00, 0xe5, 0x50, 0xc9, 0x6c, - 0x73, 0xe2, 0x80, 0xb5, 0xf6, 0x6e, 0x36, 0x2b, 0x9a, 0x1d, 0xd7, 0xb3, 0x46, 0x8d, 0xaa, 0x5c, - 0x90, 0x90, 0x7a, 0xa9, 0x84, 0x04, 0x7f, 0x40, 0x0e, 0x88, 0x33, 0x87, 0xc0, 0x95, 0x6b, 0xd5, - 0x53, 0x04, 0x17, 0x4e, 0x08, 0x25, 0x48, 0xf0, 0x67, 0x20, 0xcf, 0xbc, 0xd9, 0x1f, 0xc9, 0xd8, - 0xde, 0x88, 0x53, 0xbc, 0x33, 0xef, 0x7d, 0xdf, 0x67, 0xde, 0x7b, 0xf3, 0x26, 0x50, 0xed, 0x52, - 0x76, 0x40, 0x99, 0xe5, 0x0c, 0xa2, 0x7d, 0xeb, 0xab, 0xf5, 0x8e, 0x17, 0x39, 0xeb, 0xd6, 0x93, - 0x81, 0xd7, 0x3f, 0x34, 0x7b, 0x7d, 0x1a, 0x51, 0xb2, 0x20, 0x0c, 0xcc, 0xa1, 0x81, 0x89, 0x06, - 0xfa, 0x1a, 0x7a, 0x75, 0x1c, 0xe6, 0x09, 0xeb, 0xd8, 0xb7, 0xe7, 0xf8, 0x41, 0xe8, 0x44, 0x01, - 0x0d, 0x85, 0x80, 0x5e, 0xf2, 0xa9, 0x4f, 0xf9, 0x4f, 0x6b, 0xf8, 0x0b, 0x57, 0xdf, 0xf2, 0x29, - 0xf5, 0x1f, 0x7b, 0x16, 0xff, 0xea, 0x0c, 0xf6, 0x2c, 0x27, 0xc4, 0x88, 0xfa, 0x12, 0x6e, 0x39, + 0x14, 0xc7, 0xbd, 0x21, 0x24, 0xe1, 0xc5, 0x0d, 0xd2, 0xc4, 0x15, 0x61, 0x9d, 0xda, 0xd1, 0x16, + 0x1a, 0x27, 0xd4, 0xbb, 0x8d, 0x93, 0x03, 0x05, 0x84, 0x14, 0x37, 0x80, 0x72, 0xa8, 0x64, 0xb6, + 0x39, 0x71, 0xc0, 0x5a, 0x7b, 0x37, 0x9b, 0x15, 0xcd, 0x8e, 0xeb, 0x59, 0xa3, 0x46, 0x55, 0x2e, + 0x48, 0x48, 0xbd, 0x54, 0x42, 0x82, 0x3f, 0x20, 0x07, 0xc4, 0x99, 0x43, 0xe0, 0xca, 0xb5, 0xea, + 0xa9, 0x82, 0x0b, 0x27, 0x84, 0x12, 0x24, 0xf8, 0x33, 0x90, 0x67, 0xde, 0xec, 0x8f, 0x64, 0x6c, + 0x6f, 0xd4, 0x53, 0xbc, 0x33, 0xef, 0x7d, 0xdf, 0x67, 0xde, 0x7b, 0xf3, 0x26, 0x50, 0xed, 0x52, + 0x76, 0x48, 0x99, 0xe5, 0x0c, 0xa2, 0x03, 0xeb, 0xeb, 0x8d, 0x8e, 0x17, 0x39, 0x1b, 0xd6, 0xa3, + 0x81, 0xd7, 0x3f, 0x32, 0x7b, 0x7d, 0x1a, 0x51, 0xb2, 0x28, 0x0c, 0xcc, 0xa1, 0x81, 0x89, 0x06, + 0xfa, 0x3a, 0x7a, 0x75, 0x1c, 0xe6, 0x09, 0xeb, 0xd8, 0xb7, 0xe7, 0xf8, 0x41, 0xe8, 0x44, 0x01, + 0x0d, 0x85, 0x80, 0x5e, 0xf2, 0xa9, 0x4f, 0xf9, 0x4f, 0x6b, 0xf8, 0x0b, 0x57, 0xdf, 0xf6, 0x29, + 0xf5, 0x1f, 0x7a, 0x16, 0xff, 0xea, 0x0c, 0xf6, 0x2d, 0x27, 0xc4, 0x88, 0xfa, 0x32, 0x6e, 0x39, 0xbd, 0xc0, 0x72, 0xc2, 0x90, 0x46, 0x5c, 0x8d, 0xe1, 0x6e, 0x45, 0x05, 0xcc, 0xe1, 0x50, 0x58, - 0xec, 0xb7, 0x45, 0x44, 0x84, 0x17, 0x5b, 0x65, 0x74, 0x95, 0xc0, 0xe9, 0x73, 0x1a, 0x5f, 0x40, - 0xe9, 0xb3, 0xe1, 0xe7, 0x56, 0xb7, 0x4b, 0x07, 0x61, 0xc4, 0x6c, 0xef, 0xc9, 0xc0, 0x63, 0x11, - 0xf9, 0x04, 0x20, 0x39, 0xd2, 0xa2, 0xb6, 0xac, 0xd5, 0xe6, 0x1a, 0x77, 0x4c, 0xd4, 0x1d, 0x9e, - 0xdf, 0x14, 0x2a, 0x88, 0x62, 0xb6, 0x1c, 0xdf, 0x43, 0x5f, 0x3b, 0xe5, 0x69, 0x1c, 0x6b, 0x70, - 0xf3, 0x42, 0x00, 0xd6, 0xa3, 0x21, 0xf3, 0xc8, 0x47, 0x30, 0xeb, 0xe0, 0xda, 0xa2, 0xb6, 0x7c, - 0xad, 0x36, 0xd7, 0x28, 0x99, 0x22, 0x05, 0xa6, 0xcc, 0x8e, 0xb9, 0x15, 0x1e, 0x36, 0x8b, 0xaf, - 0x4e, 0xea, 0xb3, 0xe8, 0xbd, 0x63, 0xc7, 0x3e, 0xe4, 0xd3, 0x0c, 0xe1, 0x14, 0x27, 0x5c, 0x99, - 0x48, 0x28, 0x82, 0x67, 0x10, 0x1f, 0xc1, 0x42, 0x9a, 0x50, 0x66, 0xa0, 0x01, 0x33, 0x8e, 0xeb, - 0xf6, 0x3d, 0xc6, 0xf8, 0xf1, 0x5f, 0x6f, 0x2e, 0xfe, 0x76, 0x52, 0x2f, 0xa1, 0xfe, 0x96, 0xd8, - 0x79, 0x14, 0xf5, 0x83, 0xd0, 0xb7, 0xa5, 0xe1, 0xfb, 0xb3, 0xcf, 0x8f, 0xab, 0x85, 0x7f, 0x8f, - 0xab, 0x05, 0x63, 0x09, 0x74, 0x2e, 0xfa, 0x90, 0xba, 0x83, 0xc7, 0xde, 0x85, 0xec, 0x1a, 0x2d, - 0x0c, 0xd9, 0x72, 0xfa, 0xce, 0x41, 0x92, 0x92, 0xfb, 0x30, 0xdd, 0xe3, 0x2b, 0x98, 0xf0, 0xb2, - 0xa9, 0xe8, 0x42, 0x53, 0x38, 0x35, 0xaf, 0xbf, 0xfc, 0xb3, 0x5a, 0xb0, 0xd1, 0xc1, 0xd8, 0xcd, - 0xd6, 0x31, 0x96, 0xfc, 0x10, 0x66, 0x30, 0x63, 0xa8, 0x99, 0x27, 0xc9, 0xd2, 0xc5, 0x28, 0x01, - 0xc9, 0x70, 0x0a, 0xfa, 0x2e, 0x94, 0x95, 0x67, 0xc3, 0x90, 0xdb, 0x39, 0x0b, 0x4b, 0x5e, 0x9d, - 0xd4, 0xe7, 0x33, 0x1a, 0xa9, 0xf2, 0x1a, 0x37, 0x61, 0xa1, 0xe9, 0x75, 0xf7, 0x37, 0x1a, 0xad, - 0xbe, 0xb7, 0x17, 0x3c, 0x95, 0xb1, 0x3f, 0x80, 0x52, 0x76, 0x19, 0x83, 0xde, 0x86, 0x1b, 0x1d, + 0xec, 0xb7, 0x45, 0x44, 0x84, 0x17, 0x5b, 0x65, 0x74, 0x95, 0xc0, 0xe9, 0x73, 0x1a, 0x5f, 0x42, + 0xe9, 0xf3, 0xe1, 0xe7, 0x76, 0xb7, 0x4b, 0x07, 0x61, 0xc4, 0x6c, 0xef, 0xd1, 0xc0, 0x63, 0x11, + 0xf9, 0x14, 0x20, 0x39, 0xd2, 0x92, 0xb6, 0xa2, 0xd5, 0xe6, 0x1b, 0xb7, 0x4c, 0xd4, 0x1d, 0x9e, + 0xdf, 0x14, 0x2a, 0x88, 0x62, 0xb6, 0x1c, 0xdf, 0x43, 0x5f, 0x3b, 0xe5, 0x69, 0x9c, 0x68, 0x70, + 0xfd, 0x42, 0x00, 0xd6, 0xa3, 0x21, 0xf3, 0xc8, 0xc7, 0x30, 0xe7, 0xe0, 0xda, 0x92, 0xb6, 0xf2, + 0x5a, 0x6d, 0xbe, 0x51, 0x32, 0x45, 0x0a, 0x4c, 0x99, 0x1d, 0x73, 0x3b, 0x3c, 0x6a, 0x16, 0x5f, + 0x9c, 0xd6, 0xe7, 0xd0, 0x7b, 0xd7, 0x8e, 0x7d, 0xc8, 0x67, 0x19, 0xc2, 0x29, 0x4e, 0xb8, 0x3a, + 0x91, 0x50, 0x04, 0xcf, 0x20, 0x3e, 0x80, 0xc5, 0x34, 0xa1, 0xcc, 0x40, 0x03, 0x66, 0x1d, 0xd7, + 0xed, 0x7b, 0x8c, 0xf1, 0xe3, 0xbf, 0xd1, 0x5c, 0xfa, 0xfd, 0xb4, 0x5e, 0x42, 0xfd, 0x6d, 0xb1, + 0xf3, 0x20, 0xea, 0x07, 0xa1, 0x6f, 0x4b, 0xc3, 0x0f, 0xe6, 0x9e, 0x9e, 0x54, 0x0b, 0xff, 0x9d, + 0x54, 0x0b, 0xc6, 0x32, 0xe8, 0x5c, 0xf4, 0x3e, 0x75, 0x07, 0x0f, 0xbd, 0x0b, 0xd9, 0x35, 0x5a, + 0x18, 0xb2, 0xe5, 0xf4, 0x9d, 0xc3, 0x24, 0x25, 0x77, 0x61, 0xa6, 0xc7, 0x57, 0x30, 0xe1, 0x65, + 0x53, 0xd1, 0x85, 0xa6, 0x70, 0x6a, 0x4e, 0x3f, 0xff, 0xab, 0x5a, 0xb0, 0xd1, 0xc1, 0xd8, 0xcb, + 0xd6, 0x31, 0x96, 0xfc, 0x08, 0x66, 0x31, 0x63, 0xa8, 0x99, 0x27, 0xc9, 0xd2, 0xc5, 0x28, 0x01, + 0xc9, 0x70, 0x0a, 0xfa, 0x2e, 0x94, 0x95, 0x67, 0xc3, 0x90, 0x3b, 0x39, 0x0b, 0x4b, 0x5e, 0x9c, + 0xd6, 0x17, 0x32, 0x1a, 0xa9, 0xf2, 0x1a, 0xd7, 0x61, 0xb1, 0xe9, 0x75, 0x0f, 0x36, 0x1b, 0xad, + 0xbe, 0xb7, 0x1f, 0x3c, 0x96, 0xb1, 0x3f, 0x84, 0x52, 0x76, 0x19, 0x83, 0xde, 0x84, 0x6b, 0x1d, 0xbe, 0xde, 0xee, 0xf1, 0x0d, 0x51, 0x33, 0xbb, 0xd8, 0x49, 0x19, 0x1b, 0x4d, 0x28, 0x63, 0xe1, - 0x9a, 0x87, 0x91, 0xc7, 0x76, 0x29, 0xd6, 0x0f, 0x2b, 0x7e, 0x1b, 0x6e, 0x60, 0x21, 0xdb, 0x9d, - 0xe1, 0x3e, 0xd7, 0x28, 0xda, 0x45, 0x27, 0xe5, 0x63, 0x7c, 0x0c, 0x4b, 0x6a, 0x0d, 0x04, 0x79, - 0x07, 0xe6, 0xa5, 0x08, 0xe3, 0x3b, 0x48, 0x22, 0xa5, 0x85, 0xb9, 0xb1, 0x1d, 0xa3, 0x88, 0x85, - 0x5d, 0xca, 0xe5, 0x24, 0x4a, 0x4e, 0x95, 0x07, 0x31, 0xcc, 0x05, 0x95, 0x24, 0x2b, 0x93, 0x4f, - 0x74, 0x0f, 0x2a, 0xe9, 0xd6, 0x89, 0x4f, 0xb7, 0xb3, 0x2d, 0x69, 0xe6, 0x61, 0x2a, 0x70, 0xb9, - 0xef, 0x35, 0x7b, 0x2a, 0x70, 0x0d, 0x17, 0xaa, 0x23, 0x3d, 0x30, 0xf2, 0x16, 0xbc, 0x81, 0xa5, - 0x6c, 0xe7, 0xbd, 0x45, 0xf3, 0x4e, 0x46, 0xce, 0x78, 0x08, 0x6f, 0xa6, 0xa3, 0xec, 0x84, 0x7b, - 0xf4, 0x7f, 0xdc, 0x4d, 0xa3, 0x05, 0x8b, 0x97, 0xe5, 0x90, 0x76, 0x13, 0xae, 0x07, 0xe1, 0x1e, - 0xc5, 0x2b, 0xb2, 0xac, 0xbc, 0x76, 0x4d, 0x87, 0xc9, 0x3e, 0xb5, 0xb9, 0x75, 0xe3, 0xd7, 0x39, - 0x78, 0x8d, 0x4b, 0x92, 0x17, 0x1a, 0xc8, 0xdb, 0xc3, 0xc8, 0xaa, 0xd2, 0x5d, 0x35, 0x65, 0xf5, - 0xb5, 0x3c, 0xa6, 0x82, 0xd1, 0x58, 0x7b, 0xfe, 0xcf, 0x4f, 0x6b, 0xda, 0xd7, 0xbf, 0xff, 0xfd, - 0xdd, 0x54, 0x95, 0xdc, 0xb2, 0x94, 0xef, 0x81, 0x44, 0xf8, 0x5e, 0x83, 0x19, 0x14, 0x20, 0xb5, - 0x89, 0x31, 0x24, 0xcd, 0x6a, 0x0e, 0x4b, 0x84, 0xd9, 0x4c, 0x60, 0x56, 0xc9, 0xca, 0x58, 0x18, - 0xeb, 0x19, 0x56, 0xe0, 0x88, 0xfc, 0xac, 0x01, 0xb9, 0xdc, 0x33, 0x64, 0x63, 0x62, 0xdc, 0xcb, - 0x3d, 0xa9, 0x6f, 0x5e, 0xcd, 0xe9, 0x0a, 0xdc, 0xf1, 0x85, 0x69, 0x07, 0xae, 0xf5, 0x2c, 0x70, - 0x8f, 0xc8, 0x37, 0x1a, 0x4c, 0x8b, 0x11, 0x48, 0x56, 0x46, 0x87, 0xcd, 0x0c, 0x49, 0xbd, 0x36, - 0xd9, 0x10, 0x99, 0x6a, 0x09, 0xd3, 0x2d, 0x52, 0x56, 0x32, 0x89, 0x21, 0x4f, 0x7e, 0xd4, 0x20, - 0x3b, 0x30, 0x19, 0xb1, 0x46, 0x87, 0x51, 0x3e, 0x3d, 0xfa, 0xbd, 0xfc, 0x0e, 0xc8, 0xb7, 0x9e, - 0xf0, 0xdd, 0x21, 0x6f, 0x2b, 0xf9, 0x0e, 0xb8, 0x67, 0x3b, 0xee, 0xbf, 0x17, 0x1a, 0x14, 0xd3, - 0x63, 0x7a, 0x44, 0x13, 0x2a, 0x06, 0xfc, 0x88, 0x26, 0x54, 0xcd, 0xfc, 0x3c, 0x89, 0x13, 0xe3, - 0x7f, 0xd8, 0x78, 0x25, 0xd5, 0xd4, 0x26, 0xea, 0x6c, 0x8c, 0x79, 0x24, 0xf4, 0xf5, 0x2b, 0x78, - 0x20, 0xe7, 0x7b, 0x09, 0x67, 0x9d, 0xbc, 0x3b, 0x86, 0x33, 0xbe, 0x2a, 0x62, 0x5a, 0x1f, 0x91, - 0x5f, 0x12, 0xee, 0xcc, 0x80, 0x1f, 0xcf, 0xad, 0x7a, 0x51, 0xc6, 0x73, 0x2b, 0x5f, 0x0f, 0xe3, - 0x7e, 0xc2, 0x6d, 0x92, 0xbb, 0xb9, 0xb8, 0xc5, 0x63, 0x75, 0x44, 0x7e, 0xd0, 0x60, 0x2e, 0x35, - 0x68, 0xc9, 0xdd, 0x89, 0xb7, 0x35, 0x35, 0xde, 0xf5, 0x7a, 0x4e, 0xeb, 0xfc, 0xf9, 0x95, 0x6f, - 0xd1, 0x70, 0x6e, 0x27, 0x03, 0xa9, 0xf9, 0xe0, 0xe5, 0x59, 0x45, 0x3b, 0x3d, 0xab, 0x68, 0x7f, - 0x9d, 0x55, 0xb4, 0x6f, 0xcf, 0x2b, 0x85, 0xd3, 0xf3, 0x4a, 0xe1, 0x8f, 0xf3, 0x4a, 0xe1, 0xf3, - 0x55, 0x3f, 0x88, 0xf6, 0x07, 0x1d, 0xb3, 0x4b, 0x0f, 0xa4, 0xa0, 0xf8, 0x53, 0x67, 0xee, 0x97, - 0xd6, 0x53, 0xa1, 0x1e, 0x1d, 0xf6, 0x3c, 0xd6, 0x99, 0xe6, 0xff, 0xd5, 0x6c, 0xfc, 0x17, 0x00, - 0x00, 0xff, 0xff, 0x83, 0xfa, 0x46, 0x09, 0x54, 0x0c, 0x00, 0x00, + 0x9a, 0x47, 0x91, 0xc7, 0xf6, 0x28, 0xd6, 0x0f, 0x2b, 0x7e, 0x13, 0xae, 0x61, 0x21, 0xdb, 0x9d, + 0xe1, 0x3e, 0xd7, 0x28, 0xda, 0x45, 0x27, 0xe5, 0x63, 0x7c, 0x02, 0xcb, 0x6a, 0x0d, 0x04, 0x79, + 0x17, 0x16, 0xa4, 0x08, 0xe3, 0x3b, 0x48, 0x22, 0xa5, 0x85, 0xb9, 0xb1, 0x13, 0xa3, 0x88, 0x85, + 0x3d, 0xca, 0xe5, 0x24, 0x4a, 0x4e, 0x95, 0x7b, 0x31, 0xcc, 0x05, 0x95, 0x24, 0x2b, 0x93, 0x4f, + 0x74, 0x07, 0x2a, 0xe9, 0xd6, 0x89, 0x4f, 0xb7, 0xbb, 0x23, 0x69, 0x16, 0x60, 0x2a, 0x70, 0xb9, + 0xef, 0xb4, 0x3d, 0x15, 0xb8, 0x86, 0x0b, 0xd5, 0x91, 0x1e, 0x18, 0x79, 0x1b, 0xde, 0xc4, 0x52, + 0xb6, 0xf3, 0xde, 0xa2, 0x05, 0x27, 0x23, 0x67, 0xdc, 0x87, 0xb7, 0xd2, 0x51, 0x76, 0xc3, 0x7d, + 0xfa, 0x0a, 0x77, 0xd3, 0x68, 0xc1, 0xd2, 0x65, 0x39, 0xa4, 0xdd, 0x82, 0xe9, 0x20, 0xdc, 0xa7, + 0x78, 0x45, 0x56, 0x94, 0xd7, 0xae, 0xe9, 0x30, 0xd9, 0xa7, 0x36, 0xb7, 0x6e, 0xfc, 0x36, 0x0f, + 0xaf, 0x73, 0x49, 0xf2, 0x4c, 0x03, 0x79, 0x7b, 0x18, 0x59, 0x53, 0xba, 0xab, 0xa6, 0xac, 0xbe, + 0x9e, 0xc7, 0x54, 0x30, 0x1a, 0xeb, 0x4f, 0xff, 0xfd, 0x79, 0x5d, 0xfb, 0xe6, 0x8f, 0x7f, 0xbe, + 0x9f, 0xaa, 0x92, 0x1b, 0x96, 0xf2, 0x3d, 0x90, 0x08, 0x3f, 0x68, 0x30, 0x8b, 0x02, 0xa4, 0x36, + 0x31, 0x86, 0xa4, 0x59, 0xcb, 0x61, 0x89, 0x30, 0x5b, 0x09, 0xcc, 0x1a, 0x59, 0x1d, 0x0b, 0x63, + 0x3d, 0xc1, 0x0a, 0x1c, 0x93, 0x5f, 0x34, 0x20, 0x97, 0x7b, 0x86, 0x6c, 0x4e, 0x8c, 0x7b, 0xb9, + 0x27, 0xf5, 0xad, 0xab, 0x39, 0x5d, 0x81, 0x3b, 0xbe, 0x30, 0xed, 0xc0, 0xb5, 0x9e, 0x04, 0xee, + 0x31, 0xf9, 0x56, 0x83, 0x19, 0x31, 0x02, 0xc9, 0xea, 0xe8, 0xb0, 0x99, 0x21, 0xa9, 0xd7, 0x26, + 0x1b, 0x22, 0x53, 0x2d, 0x61, 0xba, 0x41, 0xca, 0x4a, 0x26, 0x31, 0xe4, 0xc9, 0x4f, 0x1a, 0x64, + 0x07, 0x26, 0x23, 0xd6, 0xe8, 0x30, 0xca, 0xa7, 0x47, 0xbf, 0x93, 0xdf, 0x01, 0xf9, 0x36, 0x12, + 0xbe, 0x5b, 0xe4, 0x1d, 0x25, 0xdf, 0x21, 0xf7, 0x6c, 0xc7, 0xfd, 0xf7, 0x4c, 0x83, 0x62, 0x7a, + 0x4c, 0x8f, 0x68, 0x42, 0xc5, 0x80, 0x1f, 0xd1, 0x84, 0xaa, 0x99, 0x9f, 0x27, 0x71, 0x62, 0xfc, + 0x0f, 0x1b, 0xaf, 0xa4, 0x9a, 0xda, 0x44, 0x9d, 0x8d, 0x31, 0x8f, 0x84, 0xbe, 0x71, 0x05, 0x0f, + 0xe4, 0x7c, 0x3f, 0xe1, 0xac, 0x93, 0xf7, 0xc6, 0x70, 0xc6, 0x57, 0x45, 0x4c, 0xeb, 0x63, 0xf2, + 0x6b, 0xc2, 0x9d, 0x19, 0xf0, 0xe3, 0xb9, 0x55, 0x2f, 0xca, 0x78, 0x6e, 0xe5, 0xeb, 0x61, 0xdc, + 0x4d, 0xb8, 0x4d, 0x72, 0x3b, 0x17, 0xb7, 0x78, 0xac, 0x8e, 0xc9, 0x8f, 0x1a, 0xcc, 0xa7, 0x06, + 0x2d, 0xb9, 0x3d, 0xf1, 0xb6, 0xa6, 0xc6, 0xbb, 0x5e, 0xcf, 0x69, 0x9d, 0x3f, 0xbf, 0xf2, 0x2d, + 0x1a, 0xce, 0xed, 0x64, 0x20, 0x35, 0xef, 0x3d, 0x3f, 0xab, 0x68, 0x2f, 0xcf, 0x2a, 0xda, 0xdf, + 0x67, 0x15, 0xed, 0xbb, 0xf3, 0x4a, 0xe1, 0xe5, 0x79, 0xa5, 0xf0, 0xe7, 0x79, 0xa5, 0xf0, 0xc5, + 0x9a, 0x1f, 0x44, 0x07, 0x83, 0x8e, 0xd9, 0xa5, 0x87, 0x52, 0x50, 0xfc, 0xa9, 0x33, 0xf7, 0x2b, + 0xeb, 0xb1, 0x50, 0x8f, 0x8e, 0x7a, 0x1e, 0xeb, 0xcc, 0xf0, 0xff, 0x6a, 0x36, 0xff, 0x0f, 0x00, + 0x00, 0xff, 0xff, 0x3a, 0xad, 0x37, 0x28, 0x54, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3304,7 +3304,7 @@ func (m *QueryAccountAddressByIDRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Id |= int64(b&0x7F) << shift + m.Id |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/auth/types/query.pb.gw.go b/x/auth/types/query.pb.gw.go index 5c1ff90d4753..f11d69b03cda 100644 --- a/x/auth/types/query.pb.gw.go +++ b/x/auth/types/query.pb.gw.go @@ -139,7 +139,7 @@ func request_Query_AccountAddressByID_0(ctx context.Context, marshaler runtime.M return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") } - protoReq.Id, err = runtime.Int64(val) + protoReq.Id, err = runtime.Uint64(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) @@ -166,7 +166,7 @@ func local_request_Query_AccountAddressByID_0(ctx context.Context, marshaler run return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") } - protoReq.Id, err = runtime.Int64(val) + protoReq.Id, err = runtime.Uint64(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) diff --git a/x/authz/client/testutil/grpc.go b/x/authz/client/testutil/grpc.go index f22ea3fbb910..4a3b5e793d65 100644 --- a/x/authz/client/testutil/grpc.go +++ b/x/authz/client/testutil/grpc.go @@ -5,7 +5,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil/rest" + "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" "github.com/cosmos/cosmos-sdk/x/authz/client/cli" @@ -62,7 +62,7 @@ func (s *IntegrationTestSuite) TestQueryGrantGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, _ := rest.GetRequest(tc.url) + resp, _ := testutil.GetRequest(tc.url) require := s.Require() if tc.expectErr { require.Contains(string(resp), tc.errorMsg) @@ -150,7 +150,7 @@ func (s *IntegrationTestSuite) TestQueryGrantsGRPC() { tc := tc s.Run(tc.name, func() { tc.preRun() - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) if tc.expectErr { @@ -201,7 +201,7 @@ func (s *IntegrationTestSuite) TestQueryGranterGrantsGRPC() { } for _, tc := range testCases { s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) require.NoError(err) if tc.expectErr { @@ -253,7 +253,7 @@ func (s *IntegrationTestSuite) TestQueryGranteeGrantsGRPC() { } for _, tc := range testCases { s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) require.NoError(err) if tc.expectErr { diff --git a/x/bank/keeper/deterministic_test.go b/x/bank/keeper/deterministic_test.go new file mode 100644 index 000000000000..3434c0eb2eef --- /dev/null +++ b/x/bank/keeper/deterministic_test.go @@ -0,0 +1,620 @@ +package keeper_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" + "pgregory.net/rapid" +) + +type DeterministicTestSuite struct { + suite.Suite + + ctx sdk.Context + bankKeeper keeper.BaseKeeper + authKeeper *banktestutil.MockAccountKeeper + + queryClient banktypes.QueryClient + encCfg moduletestutil.TestEncodingConfig + mintAcc *authtypes.ModuleAccount +} + +const ( + denomRegex = `[a-zA-Z][a-zA-Z0-9/:._-]{2,127}` + name = `[a-zA-Z][a-zA-Z0-9]{2,127}` +) + +func TestDeterministicTestSuite(t *testing.T) { + suite.Run(t, new(DeterministicTestSuite)) +} + +func (suite *DeterministicTestSuite) SetupTest() { + key := sdk.NewKVStoreKey(banktypes.StoreKey) + testCtx := testutil.DefaultContextWithDB(suite.T(), key, sdk.NewTransientStoreKey("transient_test")) + ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()}) + encCfg := moduletestutil.MakeTestEncodingConfig(bank.AppModuleBasic{}) + + // gomock initializations + ctrl := gomock.NewController(suite.T()) + authKeeper := banktestutil.NewMockAccountKeeper(ctrl) + + suite.ctx = ctx + suite.authKeeper = authKeeper + suite.bankKeeper = keeper.NewBaseKeeper( + encCfg.Codec, + key, + suite.authKeeper, + map[string]bool{accAddrs[4].String(): true}, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + queryHelper := baseapp.NewQueryServerTestHelper(ctx, encCfg.InterfaceRegistry) + banktypes.RegisterQueryServer(queryHelper, suite.bankKeeper) + queryClient := banktypes.NewQueryClient(queryHelper) + + suite.queryClient = queryClient + suite.encCfg = encCfg + + suite.mintAcc = authtypes.NewEmptyModuleAccount(minttypes.ModuleName, authtypes.Minter) +} + +func (suite *DeterministicTestSuite) mockMintCoins(moduleAcc *authtypes.ModuleAccount) { + suite.authKeeper.EXPECT().GetModuleAccount(suite.ctx, moduleAcc.Name).Return(moduleAcc) +} + +func (suite *DeterministicTestSuite) mockSendCoinsFromModuleToAccount(moduleAcc *authtypes.ModuleAccount, accAddr sdk.AccAddress) { + suite.authKeeper.EXPECT().GetModuleAddress(moduleAcc.Name).Return(moduleAcc.GetAddress()) + suite.authKeeper.EXPECT().GetAccount(suite.ctx, moduleAcc.GetAddress()).Return(moduleAcc) + suite.authKeeper.EXPECT().HasAccount(suite.ctx, accAddr).Return(true) +} + +func (suite *DeterministicTestSuite) mockFundAccount(receiver sdk.AccAddress) { + suite.mockMintCoins(suite.mintAcc) + suite.mockSendCoinsFromModuleToAccount(mintAcc, receiver) +} + +func (suite *DeterministicTestSuite) fundAccount(addr sdk.AccAddress, coin ...sdk.Coin) { + suite.mockFundAccount(addr) + err := banktestutil.FundAccount(suite.bankKeeper, suite.ctx, addr, sdk.NewCoins(coin...)) + suite.Require().NoError(err) +} + +func (suite *DeterministicTestSuite) getCoin(t *rapid.T) sdk.Coin { + return sdk.NewCoin( + rapid.StringMatching(denomRegex).Draw(t, "denom"), + sdk.NewInt(rapid.Int64Min(1).Draw(t, "amount")), + ) +} + +func (suite *DeterministicTestSuite) runQueryBalanceIterations(addr sdk.AccAddress, prevRes *sdk.Coin) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.Balance(suite.ctx, banktypes.NewQueryBalanceRequest(addr, prevRes.GetDenom())) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.GetBalance(), prevRes) + prevRes = res.Balance + } +} + +func (suite *DeterministicTestSuite) TestGRPCQueryBalance() { + rapid.Check(suite.T(), func(t *rapid.T) { + addr := testdata.AddressGenerator(t).Draw(t, "address") + coin := suite.getCoin(t) + suite.fundAccount(addr, coin) + + suite.runQueryBalanceIterations(addr, &coin) + }) + + addr, err := sdk.AccAddressFromBech32("cosmos139f7kncmglres2nf3h4hc4tade85ekfr8sulz5") + suite.Require().NoError(err) + + coin := sdk.NewCoin( + "denom", + sdk.NewInt(10), + ) + + suite.fundAccount(addr, coin) + suite.runQueryBalanceIterations(addr, &coin) +} + +func (suite *DeterministicTestSuite) runAllBalancesIterations(addr sdk.AccAddress, prevRes sdk.Coins) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.AllBalances(suite.ctx, &banktypes.QueryAllBalancesRequest{ + Address: addr.String(), + }) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().NotNil(res.Balances) + + suite.Require().Equal(res.GetBalances(), prevRes) + prevRes = res.GetBalances() + } +} + +func (suite *DeterministicTestSuite) TestGRPCQueryAllBalances() { + rapid.Check(suite.T(), func(t *rapid.T) { + suite.SetupTest() // reset + addr := testdata.AddressGenerator(t).Draw(t, "address") + numCoins := rapid.IntRange(1, 10).Draw(t, "num-count") + coins := make(sdk.Coins, 0, numCoins) + + for i := 0; i < numCoins; i++ { + coin := suite.getCoin(t) + + // NewCoins sorts the denoms + coins = sdk.NewCoins(append(coins, coin)...) + } + + suite.fundAccount(addr, coins...) + suite.runAllBalancesIterations(addr, coins) + }) + + suite.SetupTest() // reset + addr, err := sdk.AccAddressFromBech32("cosmos139f7kncmglres2nf3h4hc4tade85ekfr8sulz5") + suite.Require().NoError(err) + + coins := sdk.NewCoins( + sdk.NewCoin("stake", sdk.NewInt(10)), + sdk.NewCoin("denom", sdk.NewInt(100)), + ) + + suite.fundAccount(addr, coins...) + suite.runAllBalancesIterations(addr, coins) +} + +func (suite *DeterministicTestSuite) runSpendableBalancesIterations(addr sdk.AccAddress, prevRes sdk.Coins) { + suite.authKeeper.EXPECT().GetAccount(suite.ctx, addr).Return(authtypes.NewBaseAccount(addr, nil, 10087, 0)).Times(1000) + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.SpendableBalances(suite.ctx, &banktypes.QuerySpendableBalancesRequest{ + Address: addr.String(), + }) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().NotNil(res.Balances) + + suite.Require().Equal(res.GetBalances(), prevRes) + prevRes = res.GetBalances() + } +} + +func (suite *DeterministicTestSuite) TestGRPCQuerySpendableBalances() { + rapid.Check(suite.T(), func(t *rapid.T) { + suite.SetupTest() // reset + addr := testdata.AddressGenerator(t).Draw(t, "address") + numCoins := rapid.IntRange(1, 10).Draw(t, "num-count") + coins := make(sdk.Coins, 0, numCoins) + + for i := 0; i < numCoins; i++ { + coin := sdk.NewCoin( + rapid.StringMatching(denomRegex).Draw(t, "denom"), + sdk.NewInt(rapid.Int64Min(1).Draw(t, "amount")), + ) + + // NewCoins sorts the denoms + coins = sdk.NewCoins(append(coins, coin)...) + } + + suite.mockFundAccount(addr) + err := banktestutil.FundAccount(suite.bankKeeper, suite.ctx, addr, coins) + suite.Require().NoError(err) + + suite.runSpendableBalancesIterations(addr, coins) + }) + + suite.SetupTest() // reset + addr, err := sdk.AccAddressFromBech32("cosmos139f7kncmglres2nf3h4hc4tade85ekfr8sulz5") + suite.Require().NoError(err) + + coins := sdk.NewCoins( + sdk.NewCoin("stake", sdk.NewInt(10)), + sdk.NewCoin("denom", sdk.NewInt(100)), + ) + + suite.mockFundAccount(addr) + err = banktestutil.FundAccount(suite.bankKeeper, suite.ctx, addr, coins) + suite.Require().NoError(err) + + suite.runSpendableBalancesIterations(addr, coins) +} + +func (suite *DeterministicTestSuite) runTotalSupplyIterations(prevRes sdk.Coins) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.TotalSupply(suite.ctx, &banktypes.QueryTotalSupplyRequest{}) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.GetSupply(), prevRes) + prevRes = res.GetSupply() + } +} + +func (suite *DeterministicTestSuite) TestGRPCQueryTotalSupply() { + rapid.Check(suite.T(), func(t *rapid.T) { + suite.SetupTest() // reset + + res, err := suite.queryClient.TotalSupply(suite.ctx, &banktypes.QueryTotalSupplyRequest{}) + suite.Require().NoError(err) + suite.Require().NotNil(res) + genesisSupply := res.GetSupply() + + numCoins := rapid.IntRange(1, 2).Draw(t, "num-count") + coins := make(sdk.Coins, 0, numCoins) + + for i := 0; i < numCoins; i++ { + coin := sdk.NewCoin( + rapid.StringMatching(denomRegex).Draw(t, "denom"), + sdk.NewInt(rapid.Int64Min(1).Draw(t, "amount")), + ) + + coins = coins.Add(coin) + } + + suite.mockMintCoins(suite.mintAcc) + suite.Require().NoError(suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, coins)) + + coins = genesisSupply.Add(coins...) + suite.runTotalSupplyIterations(coins) + }) + + suite.SetupTest() // reset + res, err := suite.queryClient.TotalSupply(suite.ctx, &banktypes.QueryTotalSupplyRequest{}) + suite.Require().NoError(err) + suite.Require().NotNil(res) + genesisSupply := res.GetSupply() + + coins := sdk.NewCoins( + sdk.NewCoin("foo", sdk.NewInt(10)), + sdk.NewCoin("bar", sdk.NewInt(100)), + ) + + suite.mockMintCoins(suite.mintAcc) + suite.Require().NoError(suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, coins)) + + coins = genesisSupply.Add(coins...) + suite.runTotalSupplyIterations(coins) +} + +func (suite *DeterministicTestSuite) runTotalSupplyOfIterations(denom string, prevRes sdk.Coin) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.SupplyOf(suite.ctx, &banktypes.QuerySupplyOfRequest{ + Denom: denom, + }) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.GetAmount(), prevRes) + prevRes = res.GetAmount() + } +} + +func (suite *DeterministicTestSuite) TestGRPCQueryTotalSupplyOf() { + rapid.Check(suite.T(), func(t *rapid.T) { + coin := sdk.NewCoin( + rapid.StringMatching(denomRegex).Draw(t, "denom"), + sdk.NewInt(rapid.Int64Min(1).Draw(t, "amount")), + ) + + suite.mockMintCoins(suite.mintAcc) + suite.Require().NoError(suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, sdk.NewCoins(coin))) + + suite.runTotalSupplyOfIterations(coin.Denom, coin) + }) + + coin := sdk.NewCoin("bar", sdk.NewInt(100)) + + suite.mockMintCoins(suite.mintAcc) + suite.Require().NoError(suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, sdk.NewCoins(coin))) + + suite.runTotalSupplyOfIterations(coin.Denom, coin) +} + +func (suite *DeterministicTestSuite) runParamsIterations(prevRes banktypes.Params) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.Params(suite.ctx, &banktypes.QueryParamsRequest{}) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.GetParams(), prevRes) + prevRes = res.GetParams() + } +} + +func (suite *DeterministicTestSuite) TestGRPCQueryParams() { + rapid.Check(suite.T(), func(t *rapid.T) { + enabledStatus := banktypes.SendEnabled{ + Denom: rapid.StringMatching(denomRegex).Draw(t, "denom"), + Enabled: rapid.Bool().Draw(t, "status"), + } + + params := banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{&enabledStatus}, + DefaultSendEnabled: rapid.Bool().Draw(t, "send"), + } + + // SetParams overwrites `SendEnabled` to nil + suite.bankKeeper.SetParams(suite.ctx, params) + params.SendEnabled = nil + suite.runParamsIterations(params) + }) + + enabledStatus := banktypes.SendEnabled{ + Denom: "denom", + Enabled: true, + } + + params := banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{&enabledStatus}, + DefaultSendEnabled: false, + } + + // SetParams overwrites `SendEnabled` to nil + suite.bankKeeper.SetParams(suite.ctx, params) + params.SendEnabled = nil + suite.runParamsIterations(params) +} + +func (suite *DeterministicTestSuite) createAndReturnMetadatas(t *rapid.T, count int) []banktypes.Metadata { + denomsMetadata := make([]banktypes.Metadata, 0, count) + for i := 0; i < count; i++ { + + denom := rapid.StringMatching(denomRegex).Draw(t, "denom") + + metadata := banktypes.Metadata{ + Description: rapid.StringN(1, 100, 100).Draw(t, "desc"), + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: denom, + Exponent: rapid.Uint32().Draw(t, "exponent"), + Aliases: []string{denom}, + }, + }, + Base: denom, + Display: denom, + } + + denomsMetadata = append(denomsMetadata, metadata) + } + + return denomsMetadata +} + +func (suite *DeterministicTestSuite) runDenomsMetadataIterations(prevRes []banktypes.Metadata) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.DenomsMetadata(suite.ctx, &banktypes.QueryDenomsMetadataRequest{}) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + for i := 0; i < len(res.GetMetadatas()); i++ { + suite.Require().Equal(res.GetMetadatas()[i], prevRes[i]) + } + + prevRes = res.GetMetadatas() + } +} + +func (suite *DeterministicTestSuite) TestGRPCDenomsMetadata() { + rapid.Check(suite.T(), func(t *rapid.T) { + suite.SetupTest() // reset + count := rapid.IntRange(1, 5).Draw(t, "count") + denomsMetadata := suite.createAndReturnMetadatas(t, count) + suite.Require().Len(denomsMetadata, count) + + for i := 0; i < count; i++ { + suite.bankKeeper.SetDenomMetaData(suite.ctx, denomsMetadata[i]) + } + + res, err := suite.queryClient.DenomsMetadata(suite.ctx, &banktypes.QueryDenomsMetadataRequest{}) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.runDenomsMetadataIterations(res.Metadatas) + }) + + suite.SetupTest() // reset + + metadataAtom := banktypes.Metadata{ + Description: "The native staking token of the Cosmos Hub.", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + Aliases: []string{"microtest"}, + }, + { + Denom: "test", + Exponent: 6, + Aliases: []string{"TEST"}, + }, + }, + Base: "utest", + Display: "test", + } + + suite.bankKeeper.SetDenomMetaData(suite.ctx, metadataAtom) + suite.runDenomsMetadataIterations([]banktypes.Metadata{metadataAtom}) +} + +func (suite *DeterministicTestSuite) runDenomMetadataIterations(denom string, prevRes banktypes.Metadata) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.DenomMetadata(suite.ctx, &banktypes.QueryDenomMetadataRequest{ + Denom: denom, + }) + + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.GetMetadata(), prevRes) + prevRes = res.GetMetadata() + } +} + +func (suite *DeterministicTestSuite) TestGRPCDenomMetadata() { + rapid.Check(suite.T(), func(t *rapid.T) { + denomMetadata := suite.createAndReturnMetadatas(t, 1) + suite.Require().Len(denomMetadata, 1) + suite.bankKeeper.SetDenomMetaData(suite.ctx, denomMetadata[0]) + suite.runDenomMetadataIterations(denomMetadata[0].Base, denomMetadata[0]) + }) + + metadataAtom := banktypes.Metadata{ + Description: "The native staking token of the Cosmos Hub.", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + Aliases: []string{"microtest"}, + }, + { + Denom: "test", + Exponent: 6, + Aliases: []string{"TEST"}, + }, + }, + Base: "utest", + Display: "test", + } + + suite.bankKeeper.SetDenomMetaData(suite.ctx, metadataAtom) + suite.runDenomMetadataIterations(metadataAtom.Base, metadataAtom) +} + +func (suite *DeterministicTestSuite) runSendEnabledIterations(denoms []string, prevRes []*banktypes.SendEnabled) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.SendEnabled(suite.ctx, &banktypes.QuerySendEnabledRequest{ + Denoms: denoms, + }) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + suite.Require().Equal(res.SendEnabled, prevRes) + prevRes = res.SendEnabled + } +} + +func (suite *DeterministicTestSuite) TestGRPCSendEnabled() { + rapid.Check(suite.T(), func(t *rapid.T) { + count := rapid.IntRange(1, 10).Draw(t, "count") + sendEnabled := make([]*banktypes.SendEnabled, 0, count) + denoms := make([]string, 0, count) + + for i := 0; i < count; i++ { + coin := banktypes.SendEnabled{ + Denom: rapid.StringMatching(denomRegex).Draw(t, "denom"), + Enabled: rapid.Bool().Draw(t, "enabled-status"), + } + + suite.bankKeeper.SetSendEnabled(suite.ctx, coin.Denom, coin.Enabled) + sendEnabled = append(sendEnabled, &coin) + denoms = append(denoms, coin.Denom) + } + + suite.runSendEnabledIterations(denoms, sendEnabled) + }) + + coin1 := banktypes.SendEnabled{ + Denom: "falsecoin", + Enabled: false, + } + coin2 := banktypes.SendEnabled{ + Denom: "truecoin", + Enabled: true, + } + + suite.bankKeeper.SetSendEnabled(suite.ctx, coin1.Denom, false) + suite.bankKeeper.SetSendEnabled(suite.ctx, coin2.Denom, true) + + suite.runSendEnabledIterations( + []string{coin1.Denom, coin2.Denom}, + []*banktypes.SendEnabled{ + &coin1, + &coin2, + }, + ) +} + +func (suite *DeterministicTestSuite) runDenomOwnerIterations(denom string, prevRes []*banktypes.DenomOwner) { + for i := 0; i < 1000; i++ { + res, err := suite.queryClient.DenomOwners(suite.ctx, &banktypes.QueryDenomOwnersRequest{ + Denom: denom, + }) + + suite.Require().NoError(err) + suite.Require().Equal(res.DenomOwners, prevRes) + prevRes = res.DenomOwners + } +} + +func (suite *DeterministicTestSuite) TestGRPCDenomOwners() { + rapid.Check(suite.T(), func(t *rapid.T) { + denom := rapid.StringMatching(denomRegex).Draw(t, "denom") + numAddr := rapid.IntRange(1, 10).Draw(t, "number-address") + for i := 0; i < numAddr; i++ { + addr := testdata.AddressGenerator(t).Draw(t, "address") + + coin := sdk.NewCoin( + denom, + sdk.NewInt(rapid.Int64Min(1).Draw(t, "amount")), + ) + + suite.mockFundAccount(addr) + + err := banktestutil.FundAccount(suite.bankKeeper, suite.ctx, addr, sdk.NewCoins(coin)) + suite.Require().NoError(err) + } + + res, err := suite.queryClient.DenomOwners(suite.ctx, &banktypes.QueryDenomOwnersRequest{ + Denom: denom, + }) + + suite.Require().NoError(err) + suite.runDenomOwnerIterations(denom, res.DenomOwners) + }) + + coin := sdk.NewCoin( + "denom", + sdk.NewInt(10), + ) + + denomOwners := []*banktypes.DenomOwner{ + { + Address: "cosmos1qg65a9q6k2sqq7l3ycp428sqqpmqcucgzze299", + Balance: coin, + }, + { + Address: "cosmos1qglnsqgpq48l7qqzgs8qdshr6fh3gqq9ej3qut", + Balance: coin, + }, + } + + for i := 0; i < len(denomOwners); i++ { + addr, err := sdk.AccAddressFromBech32(denomOwners[i].Address) + suite.Require().NoError(err) + + suite.mockFundAccount(addr) + err = banktestutil.FundAccount(suite.bankKeeper, suite.ctx, addr, sdk.NewCoins(coin)) + suite.Require().NoError(err) + } + + suite.runDenomOwnerIterations(coin.Denom, denomOwners) +} diff --git a/x/distribution/client/testutil/grpc_query_suite.go b/x/distribution/client/testutil/grpc_query_suite.go index ddfa15a6f4b9..018f01126005 100644 --- a/x/distribution/client/testutil/grpc_query_suite.go +++ b/x/distribution/client/testutil/grpc_query_suite.go @@ -8,7 +8,6 @@ import ( sdktestutil "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/testutil/rest" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/types/query" @@ -65,7 +64,7 @@ func (s *GRPCQueryTestSuite) TestQueryParamsGRPC() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := sdktestutil.GetRequest(tc.url) s.Run(tc.name, func() { s.Require().NoError(err) s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) @@ -100,7 +99,7 @@ func (s *GRPCQueryTestSuite) TestQueryValidatorDistributionInfoGRPC() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := sdktestutil.GetRequest(tc.url) s.Run(tc.name, func() { if tc.expErr { s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) @@ -265,7 +264,7 @@ func (s *GRPCQueryTestSuite) TestQuerySlashesGRPC() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := sdktestutil.GetRequest(tc.url) s.Run(tc.name, func() { if tc.expErr { @@ -393,7 +392,7 @@ func (s *GRPCQueryTestSuite) TestQueryDelegatorValidatorsGRPC() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := sdktestutil.GetRequest(tc.url) s.Run(tc.name, func() { if tc.expErr { @@ -445,7 +444,7 @@ func (s *GRPCQueryTestSuite) TestQueryWithdrawAddressGRPC() { for _, tc := range testCases { tc := tc - resp, err := rest.GetRequest(tc.url) + resp, err := sdktestutil.GetRequest(tc.url) s.Run(tc.name, func() { if tc.expErr { diff --git a/x/distribution/keeper/hooks.go b/x/distribution/keeper/hooks.go index bfae8482da5e..aa7a68422ea2 100644 --- a/x/distribution/keeper/hooks.go +++ b/x/distribution/keeper/hooks.go @@ -14,7 +14,9 @@ type Hooks struct { var _ stakingtypes.StakingHooks = Hooks{} // Create new distribution hooks -func (k Keeper) Hooks() Hooks { return Hooks{k} } +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} // initialize validator distribution record func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { @@ -109,7 +111,10 @@ func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, f return nil } -func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error { return nil } +func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error { + return nil +} + func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { return nil } diff --git a/x/gov/abci.go b/x/gov/abci.go index f45cc68c3ff0..cc49b808f81f 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -24,7 +24,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { keeper.RefundAndDeleteDeposits(ctx, proposal.Id) // refund deposit if proposal got removed without getting 100% of the proposal // called when proposal become inactive - keeper.AfterProposalFailedMinDeposit(ctx, proposal.Id) + keeper.Hooks().AfterProposalFailedMinDeposit(ctx, proposal.Id) ctx.EventManager().EmitEvent( sdk.NewEvent( @@ -104,7 +104,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { keeper.RemoveFromActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) // when proposal become active - keeper.AfterProposalVotingPeriodEnded(ctx, proposal.Id) + keeper.Hooks().AfterProposalVotingPeriodEnded(ctx, proposal.Id) logger.Info( "proposal tallied", diff --git a/x/gov/client/testutil/grpc.go b/x/gov/client/testutil/grpc.go index 66e93ed2098c..17dec9e427e3 100644 --- a/x/gov/client/testutil/grpc.go +++ b/x/gov/client/testutil/grpc.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/rest" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" @@ -39,7 +38,7 @@ func (s *IntegrationTestSuite) TestGetProposalGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var proposal v1.QueryProposalResponse @@ -160,7 +159,7 @@ func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var vote v1.QueryVoteResponse @@ -204,7 +203,7 @@ func (s *IntegrationTestSuite) TestGetProposalVotesGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var votes v1.QueryVotesResponse @@ -253,7 +252,7 @@ func (s *IntegrationTestSuite) TestGetProposalDepositGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var deposit v1.QueryDepositResponse @@ -292,7 +291,7 @@ func (s *IntegrationTestSuite) TestGetProposalDepositsGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var deposits v1.QueryDepositsResponse @@ -337,7 +336,7 @@ func (s *IntegrationTestSuite) TestGetTallyGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) var tally v1.QueryTallyResultResponse @@ -399,7 +398,7 @@ func (s *IntegrationTestSuite) TestGetParamsGRPC() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType) diff --git a/x/gov/keeper/deposit.go b/x/gov/keeper/deposit.go index 51de86003aaa..0a25fc9975b8 100644 --- a/x/gov/keeper/deposit.go +++ b/x/gov/keeper/deposit.go @@ -147,7 +147,7 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd } // called when deposit has been added to a proposal, however the proposal may not be active - keeper.AfterProposalDeposit(ctx, proposalID, depositorAddr) + keeper.Hooks().AfterProposalDeposit(ctx, proposalID, depositorAddr) ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/x/gov/keeper/hooks.go b/x/gov/keeper/hooks.go deleted file mode 100644 index a63efdcc74f4..000000000000 --- a/x/gov/keeper/hooks.go +++ /dev/null @@ -1,44 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/gov/types" -) - -// Implements GovHooks interface -var _ types.GovHooks = Keeper{} - -// AfterProposalSubmission - call hook if registered -func (keeper Keeper) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) { - if keeper.hooks != nil { - keeper.hooks.AfterProposalSubmission(ctx, proposalID) - } -} - -// AfterProposalDeposit - call hook if registered -func (keeper Keeper) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { - if keeper.hooks != nil { - keeper.hooks.AfterProposalDeposit(ctx, proposalID, depositorAddr) - } -} - -// AfterProposalVote - call hook if registered -func (keeper Keeper) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { - if keeper.hooks != nil { - keeper.hooks.AfterProposalVote(ctx, proposalID, voterAddr) - } -} - -// AfterProposalFailedMinDeposit - call hook if registered -func (keeper Keeper) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) { - if keeper.hooks != nil { - keeper.hooks.AfterProposalFailedMinDeposit(ctx, proposalID) - } -} - -// AfterProposalVotingPeriodEnded - call hook if registered -func (keeper Keeper) AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) { - if keeper.hooks != nil { - keeper.hooks.AfterProposalVotingPeriodEnded(ctx, proposalID) - } -} diff --git a/x/gov/keeper/keeper.go b/x/gov/keeper/keeper.go index 307152f9633a..34e8e975d37e 100644 --- a/x/gov/keeper/keeper.go +++ b/x/gov/keeper/keeper.go @@ -92,6 +92,16 @@ func NewKeeper( } } +// Hooks gets the hooks for governance *Keeper { +func (keeper *Keeper) Hooks() types.GovHooks { + if keeper.hooks == nil { + // return a no-op implementation if no hooks are set + return types.MultiGovHooks{} + } + + return keeper.hooks +} + // SetHooks sets the hooks for governance func (keeper *Keeper) SetHooks(gh types.GovHooks) *Keeper { if keeper.hooks != nil { diff --git a/x/gov/keeper/proposal.go b/x/gov/keeper/proposal.go index 2eb75f4cd143..cb1807410927 100644 --- a/x/gov/keeper/proposal.go +++ b/x/gov/keeper/proposal.go @@ -82,7 +82,7 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat keeper.SetProposalID(ctx, proposalID+1) // called right after a proposal is submitted - keeper.AfterProposalSubmission(ctx, proposalID) + keeper.Hooks().AfterProposalSubmission(ctx, proposalID) ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/x/gov/keeper/vote.go b/x/gov/keeper/vote.go index 4e2436ff84b5..038310a916a4 100644 --- a/x/gov/keeper/vote.go +++ b/x/gov/keeper/vote.go @@ -33,7 +33,7 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.A keeper.SetVote(ctx, vote) // called after a vote on a proposal is cast - keeper.AfterProposalVote(ctx, proposalID, voterAddr) + keeper.Hooks().AfterProposalVote(ctx, proposalID, voterAddr) ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/simapp/config.go b/x/simulation/client/cli/flags.go similarity index 99% rename from simapp/config.go rename to x/simulation/client/cli/flags.go index 48cc053f2533..bec5b6e8b712 100644 --- a/simapp/config.go +++ b/x/simulation/client/cli/flags.go @@ -1,4 +1,4 @@ -package simapp +package cli import ( "flag" diff --git a/x/slashing/keeper/hooks.go b/x/slashing/keeper/hooks.go index a306f76c210d..01f2c2690a60 100644 --- a/x/slashing/keeper/hooks.go +++ b/x/slashing/keeper/hooks.go @@ -9,14 +9,26 @@ import ( "github.com/cosmos/cosmos-sdk/x/slashing/types" ) -func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ sdk.ValAddress) error { - // Update the signing info start height or create a new signing info - signingInfo, found := k.GetValidatorSigningInfo(ctx, address) +var _ types.StakingHooks = Hooks{} + +// Hooks wrapper struct for slashing keeper +type Hooks struct { + k Keeper +} + +// Return the slashing hooks +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} + +// AfterValidatorBonded updates the signing info start height or create a new signing info +func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { + signingInfo, found := h.k.GetValidatorSigningInfo(ctx, consAddr) if found { signingInfo.StartHeight = ctx.BlockHeight() } else { signingInfo = types.NewValidatorSigningInfo( - address, + consAddr, ctx.BlockHeight(), 0, time.Unix(0, 0), @@ -25,53 +37,26 @@ func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ ) } - k.SetValidatorSigningInfo(ctx, address, signingInfo) + h.k.SetValidatorSigningInfo(ctx, consAddr, signingInfo) return nil } +// AfterValidatorRemoved deletes the address-pubkey relation when a validator is removed, +func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) error { + h.k.deleteAddrPubkeyRelation(ctx, crypto.Address(consAddr)) + return nil +} + // AfterValidatorCreated adds the address-pubkey relation when a validator is created. -func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { - validator := k.sk.Validator(ctx, valAddr) +func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { + validator := h.k.sk.Validator(ctx, valAddr) consPk, err := validator.ConsPubKey() if err != nil { return err } - return k.AddPubkey(ctx, consPk) -} - -// AfterValidatorRemoved deletes the address-pubkey relation when a validator is removed, -func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress) error { - k.deleteAddrPubkeyRelation(ctx, crypto.Address(address)) - return nil -} - -// Hooks wrapper struct for slashing keeper -type Hooks struct { - k Keeper -} - -var _ types.StakingHooks = Hooks{} - -// Return the wrapper struct -func (k Keeper) Hooks() Hooks { - return Hooks{k} -} - -// Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { - return h.k.AfterValidatorBonded(ctx, consAddr, valAddr) -} - -// Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) error { - return h.k.AfterValidatorRemoved(ctx, consAddr) -} - -// Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { - return h.k.AfterValidatorCreated(ctx, valAddr) + return h.k.AddPubkey(ctx, consPk) } func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { diff --git a/x/slashing/keeper/hooks_test.go b/x/slashing/keeper/hooks_test.go index d07b050632f4..9fe301699953 100644 --- a/x/slashing/keeper/hooks_test.go +++ b/x/slashing/keeper/hooks_test.go @@ -11,7 +11,7 @@ func (s *KeeperTestSuite) TestAfterValidatorBonded() { require := s.Require() valAddr := sdk.ValAddress(consAddr.Bytes()) - keeper.AfterValidatorBonded(ctx, consAddr, valAddr) + keeper.Hooks().AfterValidatorBonded(ctx, consAddr, valAddr) _, ok := keeper.GetValidatorSigningInfo(ctx, consAddr) require.True(ok) @@ -28,14 +28,14 @@ func (s *KeeperTestSuite) TestAfterValidatorCreatedOrRemoved() { require.NoError(err) s.stakingKeeper.EXPECT().Validator(ctx, valAddr).Return(validator) - err = keeper.AfterValidatorCreated(ctx, valAddr) + err = keeper.Hooks().AfterValidatorCreated(ctx, valAddr) require.NoError(err) ePubKey, err := keeper.GetPubkey(ctx, addr.Bytes()) require.NoError(err) require.Equal(ePubKey, pubKey) - err = keeper.AfterValidatorRemoved(ctx, sdk.ConsAddress(addr)) + err = keeper.Hooks().AfterValidatorRemoved(ctx, sdk.ConsAddress(addr), nil) require.NoError(err) _, err = keeper.GetPubkey(ctx, addr.Bytes()) diff --git a/x/slashing/testutil/expected_keepers_mocks.go b/x/slashing/testutil/expected_keepers_mocks.go index d8d729920c69..321ca0561f44 100644 --- a/x/slashing/testutil/expected_keepers_mocks.go +++ b/x/slashing/testutil/expected_keepers_mocks.go @@ -396,6 +396,34 @@ func (m *MockStakingHooks) EXPECT() *MockStakingHooksMockRecorder { return m.recorder } +// AfterDelegationModified mocks base method. +func (m *MockStakingHooks) AfterDelegationModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterDelegationModified", ctx, delAddr, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterDelegationModified indicates an expected call of AfterDelegationModified. +func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterDelegationModified", reflect.TypeOf((*MockStakingHooks)(nil).AfterDelegationModified), ctx, delAddr, valAddr) +} + +// AfterValidatorBeginUnbonding mocks base method. +func (m *MockStakingHooks) AfterValidatorBeginUnbonding(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterValidatorBeginUnbonding", ctx, consAddr, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterValidatorBeginUnbonding indicates an expected call of AfterValidatorBeginUnbonding. +func (mr *MockStakingHooksMockRecorder) AfterValidatorBeginUnbonding(ctx, consAddr, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorBeginUnbonding", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorBeginUnbonding), ctx, consAddr, valAddr) +} + // AfterValidatorBonded mocks base method. func (m *MockStakingHooks) AfterValidatorBonded(ctx types.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error { m.ctrl.T.Helper() @@ -437,3 +465,73 @@ func (mr *MockStakingHooksMockRecorder) AfterValidatorRemoved(ctx, consAddr, val mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterValidatorRemoved", reflect.TypeOf((*MockStakingHooks)(nil).AfterValidatorRemoved), ctx, consAddr, valAddr) } + +// BeforeDelegationCreated mocks base method. +func (m *MockStakingHooks) BeforeDelegationCreated(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeforeDelegationCreated", ctx, delAddr, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// BeforeDelegationCreated indicates an expected call of BeforeDelegationCreated. +func (mr *MockStakingHooksMockRecorder) BeforeDelegationCreated(ctx, delAddr, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationCreated", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationCreated), ctx, delAddr, valAddr) +} + +// BeforeDelegationRemoved mocks base method. +func (m *MockStakingHooks) BeforeDelegationRemoved(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeforeDelegationRemoved", ctx, delAddr, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// BeforeDelegationRemoved indicates an expected call of BeforeDelegationRemoved. +func (mr *MockStakingHooksMockRecorder) BeforeDelegationRemoved(ctx, delAddr, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationRemoved", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationRemoved), ctx, delAddr, valAddr) +} + +// BeforeDelegationSharesModified mocks base method. +func (m *MockStakingHooks) BeforeDelegationSharesModified(ctx types.Context, delAddr types.AccAddress, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeforeDelegationSharesModified", ctx, delAddr, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// BeforeDelegationSharesModified indicates an expected call of BeforeDelegationSharesModified. +func (mr *MockStakingHooksMockRecorder) BeforeDelegationSharesModified(ctx, delAddr, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeDelegationSharesModified", reflect.TypeOf((*MockStakingHooks)(nil).BeforeDelegationSharesModified), ctx, delAddr, valAddr) +} + +// BeforeValidatorModified mocks base method. +func (m *MockStakingHooks) BeforeValidatorModified(ctx types.Context, valAddr types.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeforeValidatorModified", ctx, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// BeforeValidatorModified indicates an expected call of BeforeValidatorModified. +func (mr *MockStakingHooksMockRecorder) BeforeValidatorModified(ctx, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeValidatorModified", reflect.TypeOf((*MockStakingHooks)(nil).BeforeValidatorModified), ctx, valAddr) +} + +// BeforeValidatorSlashed mocks base method. +func (m *MockStakingHooks) BeforeValidatorSlashed(ctx types.Context, valAddr types.ValAddress, fraction types.Dec) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeforeValidatorSlashed", ctx, valAddr, fraction) + ret0, _ := ret[0].(error) + return ret0 +} + +// BeforeValidatorSlashed indicates an expected call of BeforeValidatorSlashed. +func (mr *MockStakingHooksMockRecorder) BeforeValidatorSlashed(ctx, valAddr, fraction interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeforeValidatorSlashed", reflect.TypeOf((*MockStakingHooks)(nil).BeforeValidatorSlashed), ctx, valAddr, fraction) +} diff --git a/x/slashing/types/expected_keepers.go b/x/slashing/types/expected_keepers.go index c4cdfec1dc53..0b1a8afe8c9c 100644 --- a/x/slashing/types/expected_keepers.go +++ b/x/slashing/types/expected_keepers.go @@ -59,7 +59,15 @@ type StakingKeeper interface { // StakingHooks event hooks for staking validator object (noalias) type StakingHooks interface { AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created + BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator's state changes AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted - AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded + AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded + AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator begins unbonding + + BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is created + BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation's shares are modified + BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed + AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error + BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error } diff --git a/x/staking/README.md b/x/staking/README.md index 4d429e87a7cb..e6ea53b42572 100644 --- a/x/staking/README.md +++ b/x/staking/README.md @@ -77,7 +77,7 @@ Store entries prefixed with "Last" must remain unchanged until EndBlock. ## Params -The staking module stores it's params in state with the prefix of `0x51`, +The staking module stores its params in state with the prefix of `0x51`, it can be updated with governance or the address with authority. * Params: `0x51 | ProtocolBuffer(Params)` @@ -90,7 +90,7 @@ Validators can have one of three statuses * `Unbonded`: The validator is not in the active set. They cannot sign blocks and do not earn rewards. They can receive delegations. -* `Bonded`: Once the validator receives sufficient bonded tokens they automtically join the +* `Bonded`: Once the validator receives sufficient bonded tokens they automatically join the active set during [`EndBlock`](./05_end_block.md#validator-set-changes) and their status is updated to `Bonded`. They are signing blocks and receiving rewards. They can receive further delegations. They can be slashed for misbehavior. Delegators to this validator who unbond their delegation @@ -272,7 +272,7 @@ the `n` most recent historical info defined by staking module parameter: `Histor At each BeginBlock, the staking keeper will persist the current Header and the Validators that committed the current block in a `HistoricalInfo` object. The Validators are sorted on their address to ensure that -they are in a determisnistic order. +they are in a deterministic order. The oldest HistoricalEntries will be pruned to ensure that there only exist the parameter-defined number of historical entries. @@ -396,7 +396,7 @@ Redelegations affect the delegation, source and destination validators. * record the token amount in an new entry in the relevant `Redelegation` From when a redelegation begins until it completes, the delegator is in a state of "pseudo-unbonding", and can still be -slashed for infractions that occured before the redelegation began. +slashed for infractions that occurred before the redelegation began. ### Complete Redelegation @@ -575,7 +575,7 @@ When this message is processed the following actions occur: ## MsgCancelUnbondingDelegation -The `MsgCancelUnbondingDelegation` message allows delegators to cancel the `unbondingDelegation` entry and deleagate back to a previous validator. +The `MsgCancelUnbondingDelegation` message allows delegators to cancel the `unbondingDelegation` entry and delegate back to a previous validator. +++ hhttps://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L36-L40 @@ -585,7 +585,7 @@ This message is expected to fail if: * the `unbondingDelegation` entry is already processed. * the `cancel unbonding delegation` amount is greater than the `unbondingDelegation` entry balance. -* the `cancel unbonding delegation` height doesn't exists in the `unbondingDelegationQueue` of the delegator. +* the `cancel unbonding delegation` height doesn't exist in the `unbondingDelegationQueue` of the delegator. When this message is processed the following actions occur: @@ -687,7 +687,7 @@ message reporting their new consensus power which is passed back to Tendermint. The `LastTotalPower` and `LastValidatorsPower` hold the state of the total power and validator power from the end of the last block, and are used to check for -changes that have occured in `ValidatorsByPower` and the total new power, which +changes that have occurred in `ValidatorsByPower` and the total new power, which is calculated during `EndBlock`. ## Queues diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index c63286e2769e..94ab596d337d 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -103,7 +103,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) e delegatorAddress := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress) // TODO: Consider calling hooks outside of the store wrapper functions, it's unobvious. - if err := k.BeforeDelegationRemoved(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + if err := k.Hooks().BeforeDelegationRemoved(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { return err } @@ -630,9 +630,9 @@ func (k Keeper) Delegate( // call the appropriate hook if present if found { - err = k.BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator()) + err = k.Hooks().BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator()) } else { - err = k.BeforeDelegationCreated(ctx, delAddr, validator.GetOperator()) + err = k.Hooks().BeforeDelegationCreated(ctx, delAddr, validator.GetOperator()) } if err != nil { @@ -689,7 +689,7 @@ func (k Keeper) Delegate( k.SetDelegation(ctx, delegation) // Call the after-modification hook - if err := k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + if err := k.Hooks().AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { return newShares, err } @@ -707,7 +707,7 @@ func (k Keeper) Unbond( } // call the before-delegation-modified hook - if err := k.BeforeDelegationSharesModified(ctx, delAddr, valAddr); err != nil { + if err := k.Hooks().BeforeDelegationSharesModified(ctx, delAddr, valAddr); err != nil { return amount, err } @@ -745,7 +745,7 @@ func (k Keeper) Unbond( } else { k.SetDelegation(ctx, delegation) // call the after delegation modification hook - err = k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) + err = k.Hooks().AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) } if err != nil { diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 0102898bb215..669818b3b34f 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -610,7 +610,7 @@ func (s *KeeperTestSuite) TestRedelegationMaxEntries() { require.Equal(valTokens, issuedShares.RoundInt()) s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any()) - validator = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true) + _ = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := stakingtypes.NewDelegation(val0AccAddr, addrVals[0], issuedShares) keeper.SetDelegation(ctx, selfDelegation) @@ -732,7 +732,7 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() { validator2, issuedShares = validator2.AddTokensFromDel(valTokens) require.Equal(valTokens, issuedShares.RoundInt()) s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any()) - validator2 = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator2, true) + _ = stakingkeeper.TestingUpdateValidator(keeper, ctx, validator2, true) header := ctx.BlockHeader() blockHeight := int64(10) diff --git a/x/staking/keeper/genesis.go b/x/staking/keeper/genesis.go index b990b600c5d8..1aeea695e2e6 100644 --- a/x/staking/keeper/genesis.go +++ b/x/staking/keeper/genesis.go @@ -41,7 +41,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab // Call the creation hook if not exported if !data.Exported { - if err := k.AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { + if err := k.Hooks().AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { panic(err) } } @@ -68,7 +68,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab // Call the before-creation hook if not exported if !data.Exported { - if err := k.BeforeDelegationCreated(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + if err := k.Hooks().BeforeDelegationCreated(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { panic(err) } } @@ -77,7 +77,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab // Call the after-modification hook if not exported if !data.Exported { - if err := k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + if err := k.Hooks().AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { panic(err) } } diff --git a/x/staking/keeper/hooks.go b/x/staking/keeper/hooks.go deleted file mode 100644 index 91375c9e3881..000000000000 --- a/x/staking/keeper/hooks.go +++ /dev/null @@ -1,89 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -// Implements StakingHooks interface -var _ types.StakingHooks = Keeper{} - -// AfterValidatorCreated - call hook if registered -func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.AfterValidatorCreated(ctx, valAddr) - } - return nil -} - -// BeforeValidatorModified - call hook if registered -func (k Keeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.BeforeValidatorModified(ctx, valAddr) - } - return nil -} - -// AfterValidatorRemoved - call hook if registered -func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.AfterValidatorRemoved(ctx, consAddr, valAddr) - } - return nil -} - -// AfterValidatorBonded - call hook if registered -func (k Keeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.AfterValidatorBonded(ctx, consAddr, valAddr) - } - return nil -} - -// AfterValidatorBeginUnbonding - call hook if registered -func (k Keeper) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.AfterValidatorBeginUnbonding(ctx, consAddr, valAddr) - } - return nil -} - -// BeforeDelegationCreated - call hook if registered -func (k Keeper) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.BeforeDelegationCreated(ctx, delAddr, valAddr) - } - return nil -} - -// BeforeDelegationSharesModified - call hook if registered -func (k Keeper) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.BeforeDelegationSharesModified(ctx, delAddr, valAddr) - } - return nil -} - -// BeforeDelegationRemoved - call hook if registered -func (k Keeper) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - k.hooks.BeforeDelegationRemoved(ctx, delAddr, valAddr) - } - return nil -} - -// AfterDelegationModified - call hook if registered -func (k Keeper) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { - if k.hooks != nil { - return k.hooks.AfterDelegationModified(ctx, delAddr, valAddr) - } - return nil -} - -// BeforeValidatorSlashed - call hook if registered -func (k Keeper) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error { - if k.hooks != nil { - return k.hooks.BeforeValidatorSlashed(ctx, valAddr, fraction) - } - return nil -} diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 975ee64f9a1b..675b0d41b067 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -66,6 +66,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } +// Hooks gets the hooks for staking *Keeper { +func (keeper *Keeper) Hooks() types.StakingHooks { + if keeper.hooks == nil { + // return a no-op implementation if no hooks are set + return types.MultiStakingHooks{} + } + + return keeper.hooks +} + // SetHooks Set the validator hooks func (k *Keeper) SetHooks(sh types.StakingHooks) { if k.hooks != nil { diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 37ee9c3e89d7..681f158a746b 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -114,7 +114,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa k.SetNewValidatorByPowerIndex(ctx, validator) // call the after-creation hook - if err := k.AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { + if err := k.Hooks().AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { return nil, err } @@ -170,7 +170,7 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida } // call the before-modification hook since we're about to update the commission - if err := k.BeforeValidatorModified(ctx, valAddr); err != nil { + if err := k.Hooks().BeforeValidatorModified(ctx, valAddr); err != nil { return nil, err } diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index c0a147510963..7b239e588f11 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -65,7 +65,9 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh operatorAddress := validator.GetOperator() // call the before-modification hook - k.BeforeValidatorModified(ctx, operatorAddress) + if err := k.Hooks().BeforeValidatorModified(ctx, operatorAddress); err != nil { + k.Logger(ctx).Error("failed to call before validator modified hook", "error", err) + } // Track remaining slash amount for the validator // This will decrease when we slash unbondings and @@ -123,7 +125,9 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh effectiveFraction = math.LegacyOneDec() } // call the before-slashed hook - k.BeforeValidatorSlashed(ctx, operatorAddress, effectiveFraction) + if err := k.Hooks().BeforeValidatorSlashed(ctx, operatorAddress, effectiveFraction); err != nil { + k.Logger(ctx).Error("failed to call before validator slashed hook", "error", err) + } } // Deduct from validator's bonded tokens and update the validator. diff --git a/x/staking/keeper/val_state_change.go b/x/staking/keeper/val_state_change.go index ea8a24ebb405..5d63c458dca5 100644 --- a/x/staking/keeper/val_state_change.go +++ b/x/staking/keeper/val_state_change.go @@ -298,7 +298,10 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) (types if err != nil { return validator, err } - k.AfterValidatorBonded(ctx, consAddr, validator.GetOperator()) + + if err := k.Hooks().AfterValidatorBonded(ctx, consAddr, validator.GetOperator()); err != nil { + return validator, err + } return validator, err } @@ -333,7 +336,10 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat if err != nil { return validator, err } - k.AfterValidatorBeginUnbonding(ctx, consAddr, validator.GetOperator()) + + if err := k.Hooks().AfterValidatorBeginUnbonding(ctx, consAddr, validator.GetOperator()); err != nil { + return validator, err + } return validator, nil } diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index afd6fc1d72b4..2589de1af881 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -183,7 +183,9 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx))) // call hooks - k.AfterValidatorRemoved(ctx, valConsAddr, validator.GetOperator()) + if err := k.Hooks().AfterValidatorRemoved(ctx, valConsAddr, validator.GetOperator()); err != nil { + k.Logger(ctx).Error("error in after validator removed hook", "error", err) + } } // get groups of validators diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index bf9c6fa2fcf1..b639360f450b 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -10,7 +10,6 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" - "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -88,11 +87,11 @@ func (s *KeeperTestSuite) TestValidatorBasics() { require := s.Require() // construct the validators - var validators [3]types.Validator + var validators [3]stakingtypes.Validator powers := []int64{9, 8, 7} for i, power := range powers { validators[i] = teststaking.NewValidator(s.T(), sdk.ValAddress(PKs[i].Address().Bytes()), PKs[i]) - validators[i].Status = types.Unbonded + validators[i].Status = stakingtypes.Unbonded validators[i].Tokens = math.ZeroInt() tokens := keeper.TokensFromConsensusPower(ctx, power) @@ -131,11 +130,11 @@ func (s *KeeperTestSuite) TestValidatorBasics() { resVals = keeper.GetLastValidators(ctx) require.Equal(1, len(resVals)) require.True(validators[0].MinEqual(&resVals[0])) - require.Equal(types.Bonded, validators[0].Status) + require.Equal(stakingtypes.Bonded, validators[0].Status) require.True(keeper.TokensFromConsensusPower(ctx, 9).Equal(validators[0].BondedTokens())) // modify a records, save, and retrieve - validators[0].Status = types.Bonded + validators[0].Status = stakingtypes.Bonded validators[0].Tokens = keeper.TokensFromConsensusPower(ctx, 10) validators[0].DelegatorShares = sdk.NewDecFromInt(validators[0].Tokens) validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], true) @@ -169,7 +168,7 @@ func (s *KeeperTestSuite) TestValidatorBasics() { func() { keeper.RemoveValidator(ctx, validators[1].GetOperator()) }) // shouldn't be able to remove if there are still tokens left - validators[1].Status = types.Unbonded + validators[1].Status = stakingtypes.Unbonded keeper.SetValidator(ctx, validators[1]) require.PanicsWithValue("attempting to remove a validator which still contains tokens", func() { keeper.RemoveValidator(ctx, validators[1].GetOperator()) }) @@ -229,7 +228,7 @@ func (s *KeeperTestSuite) TestApplyAndReturnValidatorSetUpdatesPowerDecrease() { require := s.Require() powers := []int64{100, 100} - var validators [2]types.Validator + var validators [2]stakingtypes.Validator for i, power := range powers { validators[i] = teststaking.NewValidator(s.T(), sdk.ValAddress(PKs[i].Address().Bytes()), PKs[i])