From 1b649f01eb3826ae7bd377ce052c7f1ad2c40a51 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 20 Jun 2023 11:01:30 +0200 Subject: [PATCH] refactor: merge main into feature branch with fixes (#1038) * build(deps): bump gaurav-nelson/github-action-markdown-link-check from 1.0.13 to 1.0.15 (#928) build(deps): bump gaurav-nelson/github-action-markdown-link-check Bumps [gaurav-nelson/github-action-markdown-link-check](https://github.com/gaurav-nelson/github-action-markdown-link-check) from 1.0.13 to 1.0.15. - [Release notes](https://github.com/gaurav-nelson/github-action-markdown-link-check/releases) - [Commits](https://github.com/gaurav-nelson/github-action-markdown-link-check/compare/1.0.13...1.0.15) --- updated-dependencies: - dependency-name: gaurav-nelson/github-action-markdown-link-check dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: bump hermes (#921) * bump the version of hermes used in docs and images * use the multiplatform ghcr.io build of hermes * build(deps): bump github.com/spf13/cast from 1.5.0 to 1.5.1 (#961) Bumps [github.com/spf13/cast](https://github.com/spf13/cast) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/spf13/cast/releases) - [Commits](https://github.com/spf13/cast/compare/v1.5.0...v1.5.1) --- updated-dependencies: - dependency-name: github.com/spf13/cast dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refactor: adopt the errors module to reduce the changeset for 47 (#920) adopt the errors module to reduce the changeset for 47 Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * fix!: prevent denom DOS (#931) * Merge pull request from GHSA-chqw-ff63-95r8 * squash commit of multisig fix + everything involving denom fix * rebuild proto * fix todos --------- Co-authored-by: Jehan Tremback * regen proto * fix cherrypick issues * lint * cleans * gosec * restore param, remove tech debt from tests * ibc denom as const * add check for consumer reward denom already registered * lint * remove unneeded expect --------- Co-authored-by: Jehan Tremback Co-authored-by: Marius Poke * fix: all feature branches should have CI (#958) * Update automated-tests.yml * Update build.yml * all feature branches will now run all ci jobs relevant to them --------- Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * fix!: consumer key prefix order to avoid complex migrations (#963) proper order matching v1.0.0 Co-authored-by: Marius Poke * docs: update changelog to prep for v1.3.0 release (#953) * wip * Update CHANGELOG.md * small comment * comment * progress save * another progress save * progress save * done * Update CHANGELOG.md * add denom dos entry * remove extraneous changelog entries * restore a couple entries * Changes from PR review * add entry for 963 * fix: mitigate e2e tests relaying and non-determinism (#968) * fix: mitigate e2e tests relaying non-determinism * fix: bump signed blocks windows in e2e test configs * deps: bump cometbft to v0.34.28 (#906) this bumps only cometbft Co-authored-by: MSalopek * fix!: Remove panics on failure to send IBC packets (#876) * provider: replace panic with StopConsumerChain * provider: replace panic with error message * Info logging on client expiration * add test for consumer * add test for provider * linter * Update CHANGELOG.md --------- Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * build(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.3 (#969) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * build(deps): bump slackapi/slack-github-action from 1.23.0 to 1.24.0 (#971) Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.23.0 to 1.24.0. - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Commits](https://github.com/slackapi/slack-github-action/compare/v1.23.0...v1.24.0) --- updated-dependencies: - dependency-name: slackapi/slack-github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refactor!: upgrade ICS imports to v2 (#974) * v2 imports * Update CHANGELOG.md * docs: update PR template to consider migrations (#976) Update PULL_REQUEST_TEMPLATE.md * fix: v2 imports proto go_package option (#978) * add v2 to proto files, adjust protocgen scripts * regen proto * fix: partially revert key assignment type safety PR (#980) * use bytes in place where possible * fix tests * add v2 to proto files, adjust protocgen scripts * regen proto * change protos, define custom types, fix references * Update key_assignment_test.go * Update key_assignment.go * format * Update CHANGELOG.md * nit for better diff * docs: update top level readme for repo (#981) * Update base.css * Update README.md * smol --------- Co-authored-by: Marius Poke * ci: makefile target for checking if protos are updated (#979) * proto-check makefile target * comment * add to GH actions workflow * put proto check before other tests * gotta regenerate protos --------- Co-authored-by: Marius Poke * build(deps): bump github.com/cosmos/ibc-go/v4 from 4.4.0 to 4.4.2 (#982) * build(deps): bump github.com/cosmos/ibc-go/v4 from 4.4.0 to 4.4.2 Bumps [github.com/cosmos/ibc-go/v4](https://github.com/cosmos/ibc-go) from 4.4.0 to 4.4.2. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v4.4.0...v4.4.2) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * update changelog --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * build(deps): bump JamesIves/github-pages-deploy-action from 4.4.1 to 4.4.2 (#983) build(deps): bump JamesIves/github-pages-deploy-action Bumps [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) from 4.4.1 to 4.4.2. - [Release notes](https://github.com/JamesIves/github-pages-deploy-action/releases) - [Commits](https://github.com/JamesIves/github-pages-deploy-action/compare/v4.4.1...v4.4.2) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * build(deps): bump github.com/stretchr/testify from 1.8.3 to 1.8.4 (#985) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.3 to 1.8.4. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.3...v1.8.4) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marius Poke * feat: v2 migrations (#975) * v2 imports * Squashed commit of the following: commit a4c9224f854ecef9b8a0216a4c348c13368cdd06 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Wed May 24 10:13:10 2023 -0700 Revert "Merge branch 'shawn/v2-imports' into shawn/ccv-migrations" This reverts commit 53e3362749c05de1a44da1bbe632d8b7265eee5a, reversing changes made to 9c3f3380cbffe43f3a6d2c2b5e71c1412869786d. commit 6885ad1dffed403e21fe5a97421d21afe321ae98 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Wed May 24 10:12:49 2023 -0700 Revert "Merge branch 'shawn/v2-imports' into shawn/ccv-migrations" This reverts commit 45d74c70ff6e41d585255f039c5f814340e4bed1, reversing changes made to 53e3362749c05de1a44da1bbe632d8b7265eee5a. commit 958914412a72ebd2b79dccdfd92ec43104a431bb Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 14:48:06 2023 -0700 provider migration boilerplate commit 9521ecb3a8b9e7d87df183f879b3680bf65613e3 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:25:14 2023 -0700 lint commit fc3f27364c283aef53c305730f75f0e9e299d60b Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:20:33 2023 -0700 old default params commit 80a490cb57dc684dd740a27d753508f0a118c174 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:15:30 2023 -0700 naming commit 45d74c70ff6e41d585255f039c5f814340e4bed1 Merge: 53e33627 8e6bdfb2 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:12:03 2023 -0700 Merge branch 'shawn/v2-imports' into shawn/ccv-migrations commit 8e6bdfb21f53374874c3ea102ce04fe07f162b1d Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:10:22 2023 -0700 proto name for gov prop registration commit 53e3362749c05de1a44da1bbe632d8b7265eee5a Merge: 9c3f3380 5ca68d14 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 12:05:39 2023 -0700 Merge branch 'shawn/v2-imports' into shawn/ccv-migrations commit 5ca68d142070a8995b34c5111bc8e85363eac257 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 11:53:12 2023 -0700 fix e2e tests commit aa6bd0c87c93f6b1963ce7d71b51e22afe35b821 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 11:42:47 2023 -0700 rm bad files commit 6e3dc88d5a08cdaf039b0eef9c078e4461278f82 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 11:42:14 2023 -0700 correct generation commit 056ef7a71ef2b78ee22442be4978e02da9f2ca27 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 11:29:45 2023 -0700 proto upgrade too commit 9c3f3380cbffe43f3a6d2c2b5e71c1412869786d Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 10:57:25 2023 -0700 remove hardcoded old code commit 1e731730f34dd9bc5a0dda6a63095d9703c4379b Merge: dbf9dede 8769fd56 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 10:07:31 2023 -0700 Merge branch 'shawn/v2-imports' into shawn/ccv-migrations commit 8769fd5649713445c1770b8eb98d88ba5ded2d84 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Tue May 23 09:58:28 2023 -0700 v2 imports commit dbf9dede2a8935098cddae7db111b86659f92a4a Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Mon May 22 16:10:05 2023 -0700 provider migration commit 2d95e2e41bcf9812b5a22e06de8e5444ce0ed60a Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Mon May 22 15:01:47 2023 -0700 improve consumer test commit 85f4cfdd418d464bdd935f0ae2ceab6fe04e73c2 Author: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Date: Mon May 22 14:03:20 2023 -0700 consumer params * rm old code * go.mod restore * better naming of hardcodes * consumer boilerplate * comments * migrate consumer genesis states * test and cleans * lint * migration and partial test * cleans * finish test * comments and doc * Update migration_test.go * Update CHANGELOG.md * expand in changelog * increment consensus ver * set key table on construction * rm semver migration funcs * comment explaining consensus version * docs: cleanup changelog for v2.0.0 on main (#988) cleans * chore: Hardcode golangci-lint version (#990) * Hardcode golangci-lint version * Hardcode version in CI config * docs: Increase the validator set of cosmos hub to 180 from 175 (#999) Updated number of validators to 180 * fix: proper consumer key prefix ordering (#991) * Update keys.go * tests * fix another bug * fix comments * feat: Remove consumer genesis migration on provider (#997) * Update keys.go * tests * fix another bug * remove consumer genesis deletion, link to test * remove unused bond denom method * Revert "remove unused bond denom method" This reverts commit f930eca428bade49a05368fe5dae2d96842659cc. * remove test too * update changelog * docs: Update reward-distribution.md (#994) * Update reward-distribution.md * docs: add instructions for registering denoms * Update docs/docs/features/reward-distribution.md Co-authored-by: Marius Poke * Update reward-distribution.md * Update docs/docs/features/reward-distribution.md Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> --------- Co-authored-by: MSalopek Co-authored-by: Marius Poke * chore: update workflow re. issues and PRs (#1002) * update PR workflow * update issue workflow * rename other.md to others.md * fix typo --------- Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * docs(adr): ADR-007 pause unbonding period during equivocation proposal (#964) * docs(adr): pause unbonding period during equivocation proposal Co-authored-by: Albert Le Batteux Co-authored-by: Giuseppe Natale * fix voting period duration * remove issue reference * docs: filter out unbonding operations before pause/unpause Co-authored-by: Albert Le Batteux Co-authored-by: Giuseppe Natale --------- Co-authored-by: Albert Le Batteux Co-authored-by: Giuseppe Natale * docs: Add type prefix link to CONTRIBUTING.md (#1007) Update CONTRIBUTING.md * chore: enable mergify (#1009) * add config for mergify * enable security dependecies for v2.0.x * Markdownlint (#907) markdownlint Co-authored-by: Jacob Gadikian * fix: limit vsc matured packets handled per endblocker (#1004) * initial implementation, still need tests * UTs * integration test * linter * Update CHANGELOG.md * make vsc matured handled this block a var * comment * feat: integrate cometmock (#989) * Add gorelayer and CometMock to Dockerfile * Add option to start with cometmock in start-chain script * Start adding support for rly * Adjust relayer start action * Add entrypoint for short happy path steps * Add . nosec G204 and waiting for blocks * Adjust rly config: Gas is free * Remove optout steps from short happy path * Use separate redelegate step for short happy path * Wait for blocks after unbonding * Make naming more descriptive and add comments * Add comment to chain name sorting and improve comments * Update start-chain.sh Address comments form joint review session with @MSalopek * Fix typo * docs: Create adr-004-denom-dos-fixes.md (#934) * Create adr-006-denom-dos-fixes * Update docs/docs/adrs/adr-006-denom-dos-fixes Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * Update docs/docs/adrs/adr-006-denom-dos-fixes Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> * Update docs/docs/adrs/adr-006-denom-dos-fixes Co-authored-by: Marius Poke * Update docs/docs/adrs/adr-006-denom-dos-fixes * Update docs/docs/adrs/adr-006-denom-dos-fixes * rename to adr 004 * remove extra file * add entry to Table of Contents * add ADR 7 to ToC --------- Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Co-authored-by: Marius Poke * docs: Fix link to template (#1027) Fix link to template Fixes typo in contributing.md * feat!: Add DistributionTransmissionChannel to ConsumerAdditionProposal (#965) * update proto * remove transfer_channel_id from consumer genesis * ConsumerAdditionProposal: transfer_channel_id -> distribution_transmission_channel * send updated ConsumerAdditionProposal * validate consumer genesis param * remove StandaloneTransferChannelID from store * fix TestOnChanOpenAck * remove state breaking change * finalize merge and fix issues * chore: update docs and changelog * chore: regenerate protos * re-add integrationt tests around changeover * mv entry in changelog * test: add sovereign to consumer changeover e2e (#1025) * tests: add sovereign to consumer e2e test * rm unused bash scripts * partially address review comments * apply remaining review comments * chore: apply formatting rules --------- Co-authored-by: MSalopek * docs: ADR for throttle with retries (#1005) * all of ADR is filled out except design portion * design * Update adr-008-throttle-retries.md * Update adr-008-throttle-retries.md * Update adr-008-throttle-retries.md * Apply suggestions from code review Co-authored-by: Marius Poke * nit formatting * describe consumer changes first * add comment on rareness of throttling being triggered * split out paragraph * hopefully better explanation * Update adr-008-throttle-retries.md * accepted * TOC entry --------- Co-authored-by: Marius Poke * Add time and block advancement integration for CometMock (#1017) * Add time and block advancement * Adhere to gocritic: use += * Remove extra debug output * Fix: use correct key when consumer key is not assigned * Correct private key address field * Clarify comment for WaitTime * Use bool instead of *bool type * Add review comments * refactor: first batch of post-merge changes * refactor: batch sovereign changes with v47 * refactor: another batch of post-merge changes * changes to go.mod * refactor: final batch of changes post-merge * refactor: rebuild protos for v47 * refactor: rebuild mocks for v47 * refactor: testing changes * refactor: update proto tooling and rebuild protos * lint: appease gosec * chore: rm unused string from Makefile * chore: rm unused in makefile .phony * temporarily disable proto-check to run automated tests --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jacob Gadikian Co-authored-by: Shawn <44221603+smarshall-spitzbart@users.noreply.github.com> Co-authored-by: Jehan Tremback Co-authored-by: Marius Poke Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: Milan Mulji <98309852+mmulji-ic@users.noreply.github.com> Co-authored-by: Thomas Bruyelle Co-authored-by: Albert Le Batteux Co-authored-by: Giuseppe Natale Co-authored-by: Ruslan Akhtariev <46343690+pysel@users.noreply.github.com> Co-authored-by: Jehan --- .github/ISSUE_TEMPLATE/epic-template.md | 8 +- .github/ISSUE_TEMPLATE/feature-request.md | 16 +- .github/ISSUE_TEMPLATE/issue-template.md | 6 +- .github/PULL_REQUEST_TEMPLATE.md | 52 +- .../{other.md => others.md} | 0 .github/PULL_REQUEST_TEMPLATE/production.md | 48 + .github/dependabot.yml | 10 + .github/workflows/automated-tests.yml | 4 +- .github/workflows/build.yml | 1 + .github/workflows/codeql.yml | 15 +- .github/workflows/deploy-docs.yml | 3 +- .github/workflows/golangci-lint.yml | 1 + .github/workflows/gosec.yml | 2 + .github/workflows/nightly-e2e.yml | 2 +- .markdownlint.json | 4 + .mergify.yml | 20 + CHANGELOG.md | 125 +- CONTRIBUTING.md | 14 +- Dockerfile | 10 +- Dockerfile.gaia | 2 +- Makefile | 42 +- README.md | 6 +- .../ante/forbidden_proposals_ante_test.go | 4 +- app/consumer-democracy/ante_handler.go | 16 +- app/consumer-democracy/app.go | 46 +- .../proposals_whitelisting_test.go | 6 +- .../ante/disabled_modules_ante_test.go | 4 +- app/consumer/ante/msg_filter_ante_test.go | 4 +- app/consumer/ante_handler.go | 15 +- app/consumer/app.go | 39 +- app/provider/ante_handler.go | 11 +- app/provider/app.go | 63 +- app/sovereign/ante_handler.go | 54 + app/sovereign/app.go | 872 ++++++++++ app/sovereign/export.go | 196 +++ app/sovereign/genesis.go | 21 + cmd/interchain-security-cd/cmd/root.go | 4 +- cmd/interchain-security-cd/main.go | 4 +- cmd/interchain-security-cdd/cmd/root.go | 5 +- cmd/interchain-security-cdd/main.go | 4 +- cmd/interchain-security-pd/cmd/root.go | 5 +- cmd/interchain-security-pd/main.go | 4 +- cmd/interchain-security-sd/cmd/root.go | 307 ++++ cmd/interchain-security-sd/main.go | 24 + docs/docs/adrs/adr-004-denom-dos-fixes | 53 + .../adr-007-pause-unbonding-on-eqv-prop.md | 93 ++ docs/docs/adrs/adr-008-throttle-retries.md | 105 ++ docs/docs/adrs/intro.md | 5 +- docs/docs/consumer-development/onboarding.md | 7 + docs/docs/features/proposals.md | 3 + docs/docs/features/reward-distribution.md | 19 +- docs/docs/validators/overview.md | 2 +- docs/src/css/base.css | 1 - go.mod | 11 +- legacy_ibc_testing/simapp/test_helpers.go | 2 +- legacy_ibc_testing/testing/app.go | 6 +- legacy_ibc_testing/testing/chain.go | 9 +- .../ccv/consumer/v1/consumer.proto | 26 +- .../ccv/consumer/v1/genesis.proto | 29 +- .../ccv/consumer/v1/query.proto | 8 +- .../ccv/provider/v1/genesis.proto | 48 +- .../ccv/provider/v1/provider.proto | 261 +-- .../ccv/provider/v1/query.proto | 72 +- .../ccv/provider/v1/tx.proto | 29 +- proto/interchain_security/ccv/v1/ccv.proto | 30 +- scripts/protocgen.sh | 2 +- tests/difference/core/driver/core_test.go | 12 +- tests/difference/core/driver/setup.go | 22 +- tests/e2e/actions.go | 618 ++++++- tests/e2e/actions_sovereign_chain.go | 166 ++ tests/e2e/config.go | 106 +- tests/e2e/main.go | 40 +- tests/e2e/state.go | 125 +- tests/e2e/step_delegation.go | 71 +- tests/e2e/steps.go | 36 +- tests/e2e/steps_democracy.go | 52 +- tests/e2e/steps_double_sign.go | 9 +- tests/e2e/steps_downtime.go | 24 +- tests/e2e/steps_multi_consumer_delegation.go | 18 +- tests/e2e/steps_multi_consumer_double_sign.go | 15 +- tests/e2e/steps_multi_consumer_downtime.go | 27 +- tests/e2e/steps_reward_denom.go | 285 ++++ tests/e2e/steps_sovereign_changeover.go | 367 +++++ tests/e2e/steps_start_chains.go | 3 +- tests/e2e/steps_stop_chain.go | 6 +- .../e2e/steps_submit_equivocation_proposal.go | 3 +- .../testnet-scripts/sovereign-genesis.json | 281 ++++ tests/e2e/testnet-scripts/start-chain.sh | 65 +- tests/e2e/testnet-scripts/start-changeover.sh | 187 +++ tests/e2e/testnet-scripts/start-sovereign.sh | 133 ++ tests/integration/changeover.go | 2 +- tests/integration/common.go | 10 +- tests/integration/democracy.go | 8 +- tests/integration/distribution.go | 103 +- tests/integration/expired_client.go | 5 +- tests/integration/instance_test.go | 10 +- tests/integration/key_assignment.go | 5 +- tests/integration/normal_operations.go | 2 +- tests/integration/setup.go | 10 +- tests/integration/slashing.go | 11 +- tests/integration/stop_consumer.go | 9 +- tests/integration/throttle.go | 92 +- tests/integration/unbonding.go | 4 +- tests/integration/valset_update.go | 2 +- testutil/crypto/crypto.go | 2 +- testutil/ibc_testing/generic_setup.go | 8 +- testutil/ibc_testing/specific_setup.go | 8 +- testutil/integration/debug_test.go | 14 +- testutil/integration/interfaces.go | 20 +- testutil/keeper/expectations.go | 8 +- testutil/keeper/mocks.go | 64 +- testutil/keeper/unit_test_helpers.go | 39 +- testutil/simibc/chain_util.go | 4 +- testutil/simibc/relay_util.go | 8 +- testutil/simibc/relayed_path.go | 2 +- x/ccv/consumer/client/cli/query.go | 2 +- x/ccv/consumer/ibc_module.go | 51 +- x/ccv/consumer/ibc_module_test.go | 48 +- x/ccv/consumer/keeper/changeover.go | 1 + x/ccv/consumer/keeper/changeover_test.go | 4 +- x/ccv/consumer/keeper/distribution.go | 82 +- x/ccv/consumer/keeper/distribution_test.go | 27 +- x/ccv/consumer/keeper/genesis.go | 4 +- x/ccv/consumer/keeper/genesis_test.go | 12 +- x/ccv/consumer/keeper/grpc_query.go | 2 +- x/ccv/consumer/keeper/hooks.go | 2 +- x/ccv/consumer/keeper/keeper.go | 37 +- x/ccv/consumer/keeper/keeper_test.go | 23 +- x/ccv/consumer/keeper/params.go | 18 +- x/ccv/consumer/keeper/params_test.go | 12 +- x/ccv/consumer/keeper/relay.go | 21 +- x/ccv/consumer/keeper/relay_test.go | 35 +- x/ccv/consumer/keeper/soft_opt_out.go | 2 +- x/ccv/consumer/keeper/soft_opt_out_test.go | 8 +- x/ccv/consumer/keeper/validators.go | 2 +- x/ccv/consumer/keeper/validators_test.go | 8 +- x/ccv/consumer/module.go | 26 +- x/ccv/consumer/types/consumer.pb.go | 220 ++- x/ccv/consumer/types/errors.go | 5 +- x/ccv/consumer/types/genesis.go | 46 +- x/ccv/consumer/types/genesis.pb.go | 103 +- x/ccv/consumer/types/genesis_test.go | 31 +- x/ccv/consumer/types/keys.go | 104 +- x/ccv/consumer/types/keys_test.go | 18 +- x/ccv/consumer/types/params.go | 68 +- x/ccv/consumer/types/params_test.go | 40 +- x/ccv/consumer/types/query.pb.go | 64 +- x/ccv/consumer/types/validator.go | 6 +- x/ccv/democracy/distribution/module.go | 2 +- x/ccv/provider/client/cli/query.go | 38 +- x/ccv/provider/client/cli/tx.go | 39 +- x/ccv/provider/client/proposal_handler.go | 11 +- x/ccv/provider/handler.go | 13 +- x/ccv/provider/handler_test.go | 10 +- x/ccv/provider/ibc_module.go | 32 +- x/ccv/provider/ibc_module_test.go | 37 +- x/ccv/provider/keeper/distribution.go | 90 +- x/ccv/provider/keeper/distribution_test.go | 48 + x/ccv/provider/keeper/genesis.go | 14 +- x/ccv/provider/keeper/genesis_test.go | 22 +- x/ccv/provider/keeper/grpc_query.go | 22 +- x/ccv/provider/keeper/hooks.go | 11 +- x/ccv/provider/keeper/hooks_test.go | 6 +- x/ccv/provider/keeper/keeper.go | 129 +- x/ccv/provider/keeper/keeper_test.go | 15 +- x/ccv/provider/keeper/key_assignment.go | 70 +- x/ccv/provider/keeper/key_assignment_test.go | 54 +- x/ccv/provider/keeper/msg_server.go | 32 +- x/ccv/provider/keeper/params.go | 14 +- x/ccv/provider/keeper/params_test.go | 10 +- x/ccv/provider/keeper/proposal.go | 24 +- x/ccv/provider/keeper/proposal_test.go | 24 +- x/ccv/provider/keeper/relay.go | 46 +- x/ccv/provider/keeper/relay_test.go | 50 +- x/ccv/provider/keeper/throttle.go | 51 +- x/ccv/provider/keeper/throttle_test.go | 16 +- x/ccv/provider/module.go | 22 +- x/ccv/provider/module_test.go | 12 +- x/ccv/provider/proposal_handler.go | 13 +- x/ccv/provider/proposal_handler_test.go | 12 +- x/ccv/provider/types/codec.go | 5 + x/ccv/provider/types/consumer.go | 4 +- x/ccv/provider/types/errors.go | 30 +- x/ccv/provider/types/genesis.go | 19 +- x/ccv/provider/types/genesis.pb.go | 118 +- x/ccv/provider/types/genesis_test.go | 73 +- x/ccv/provider/types/key_assignment.go | 44 +- x/ccv/provider/types/keys.go | 21 +- x/ccv/provider/types/keys_test.go | 6 +- x/ccv/provider/types/msg.go | 48 +- x/ccv/provider/types/params.go | 69 +- x/ccv/provider/types/params_test.go | 45 +- x/ccv/provider/types/proposal.go | 41 +- x/ccv/provider/types/proposal_test.go | 33 +- x/ccv/provider/types/provider.pb.go | 1451 +++++++---------- x/ccv/provider/types/query.pb.go | 534 ++++-- x/ccv/provider/types/query.pb.gw.go | 65 + x/ccv/provider/types/throttle.go | 2 +- x/ccv/provider/types/tx.pb.go | 424 ++++- x/ccv/types/ccv.go | 12 +- x/ccv/types/ccv.pb.go | 89 +- x/ccv/types/ccv_test.go | 2 +- x/ccv/types/errors.go | 40 +- x/ccv/types/events.go | 16 +- x/ccv/types/expected_keepers.go | 6 +- x/ccv/types/shared_params.go | 10 + x/ccv/types/utils.go | 6 +- x/ccv/types/utils_test.go | 4 +- 208 files changed, 8735 insertions(+), 2644 deletions(-) rename .github/PULL_REQUEST_TEMPLATE/{other.md => others.md} (100%) create mode 100644 .github/PULL_REQUEST_TEMPLATE/production.md create mode 100644 .markdownlint.json create mode 100644 .mergify.yml create mode 100644 app/sovereign/ante_handler.go create mode 100644 app/sovereign/app.go create mode 100644 app/sovereign/export.go create mode 100644 app/sovereign/genesis.go create mode 100644 cmd/interchain-security-sd/cmd/root.go create mode 100644 cmd/interchain-security-sd/main.go create mode 100644 docs/docs/adrs/adr-004-denom-dos-fixes create mode 100644 docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md create mode 100644 docs/docs/adrs/adr-008-throttle-retries.md create mode 100644 tests/e2e/actions_sovereign_chain.go create mode 100644 tests/e2e/steps_reward_denom.go create mode 100644 tests/e2e/steps_sovereign_changeover.go create mode 100644 tests/e2e/testnet-scripts/sovereign-genesis.json create mode 100644 tests/e2e/testnet-scripts/start-changeover.sh create mode 100644 tests/e2e/testnet-scripts/start-sovereign.sh create mode 100644 x/ccv/provider/keeper/distribution_test.go diff --git a/.github/ISSUE_TEMPLATE/epic-template.md b/.github/ISSUE_TEMPLATE/epic-template.md index ff49d57323..6738bb12d1 100644 --- a/.github/ISSUE_TEMPLATE/epic-template.md +++ b/.github/ISSUE_TEMPLATE/epic-template.md @@ -4,20 +4,20 @@ about: Basic template for EPICs (used by the team) labels: epic, needs-triage --- -# Problem +## Problem -# Closing criteria +## Closing criteria -# Problem details +## Problem details -# Task list +## Task list ```[tasklist] ### Must have diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index e16a421183..44f19495cd 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,7 +1,7 @@ --- name: Feature Request about: Create a proposal to request a feature -labels: enhancement, needs-triage +labels: enhancement, epic, needs-triage --- +## Task list + +```[tasklist] +### Must have +- [ ] discuss proposal (if proposal rejected, close EPIC) +- [ ] create ADR (if ADR rejected, close EPIC) +- [ ] add sub-tasks needed to implement the proposed feature +``` + +```[tasklist] +### Nice to have +- [ ] add sub-tasks that are nice to have for the proposed feature +``` + ____ #### For Admin Use diff --git a/.github/ISSUE_TEMPLATE/issue-template.md b/.github/ISSUE_TEMPLATE/issue-template.md index 2ce98fd81b..bef74bd4bb 100644 --- a/.github/ISSUE_TEMPLATE/issue-template.md +++ b/.github/ISSUE_TEMPLATE/issue-template.md @@ -10,15 +10,15 @@ v Before smashing the submit button please review the template. v Please also ensure that this is not a duplicate issue :) ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> -# Problem +## Problem -# Closing criteria +## Closing criteria -# Problem details +## Problem details diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 936fe1c59f..1036e0b387 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,49 +1,5 @@ - +Please go the the `Preview` tab and select the appropriate sub-template: -## Description - -Closes: #XXXX - - - ---- - -### Author Checklist - -*All items are required. Please add a note to the item if the item is not applicable and -please add links to any relevant follow up issues.* - -I have... - -* [ ] Included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title -* [ ] Added `!` to the type prefix if API or client breaking change -* [ ] Targeted the correct branch (see [PR Targeting](https://github.com/cosmos/interchain-security/blob/main/CONTRIBUTING.md#pr-targeting)) -* [ ] Provided a link to the relevant issue or specification -* [ ] Followed the guidelines for [building SDK modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules) -* [ ] Included the necessary unit and integration [tests](https://github.com/cosmos/interchain-security/blob/main/CONTRIBUTING.md#testing) -* [ ] Added a changelog entry to `CHANGELOG.md` -* [ ] Included comments for [documenting Go code](https://blog.golang.org/godoc) -* [ ] Updated the relevant documentation or specification -* [ ] Reviewed "Files changed" and left comments if necessary -* [ ] Confirmed all CI checks have passed - -### Reviewers Checklist - -*All items are required. Please add a note if the item is not applicable and please add -your handle next to the items reviewed if you only reviewed selected items.* - -I have... - -* [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title -* [ ] confirmed `!` in the type prefix if API or client breaking change -* [ ] confirmed all author checklist items have been addressed -* [ ] reviewed state machine logic -* [ ] reviewed API design and naming -* [ ] reviewed documentation is accurate -* [ ] reviewed tests and test coverage +* [Production code](?expand=1&template=production.md) - for types `fix`, `feat`, and `refactor`. +* [Docs](?expand=1&template=docs.md) - for documentation changes. +* [Others](?expand=1&template=others.md) - for changes that do not affect production code. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/other.md b/.github/PULL_REQUEST_TEMPLATE/others.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE/other.md rename to .github/PULL_REQUEST_TEMPLATE/others.md diff --git a/.github/PULL_REQUEST_TEMPLATE/production.md b/.github/PULL_REQUEST_TEMPLATE/production.md new file mode 100644 index 0000000000..0d197d890c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/production.md @@ -0,0 +1,48 @@ + + +## Description + +Closes: #XXXX + + + +--- + +### Author Checklist + +*All items are required. Please add a note to the item if the item is not applicable and +please add links to any relevant follow up issues.* + +I have... + +* [ ] Included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title +* [ ] Added `!` to the type prefix if API or client breaking change +* [ ] Confirmed this PR does not introduce changes requiring state migrations, OR migration code has been added to consumer and/or provider modules +* [ ] Targeted the correct branch (see [PR Targeting](https://github.com/cosmos/interchain-security/blob/main/CONTRIBUTING.md#pr-targeting)) +* [ ] Provided a link to the relevant issue or specification +* [ ] Followed the guidelines for [building SDK modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules) +* [ ] Included the necessary unit and integration [tests](https://github.com/cosmos/interchain-security/blob/main/CONTRIBUTING.md#testing) +* [ ] Added a changelog entry to `CHANGELOG.md` +* [ ] Included comments for [documenting Go code](https://blog.golang.org/godoc) +* [ ] Updated the relevant documentation or specification +* [ ] Reviewed "Files changed" and left comments if necessary +* [ ] Confirmed all CI checks have passed + +### Reviewers Checklist + +*All items are required. Please add a note if the item is not applicable and please add +your handle next to the items reviewed if you only reviewed selected items.* + +I have... + +* [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title +* [ ] confirmed `!` in the type prefix if API or client breaking change +* [ ] confirmed this PR does not introduce changes requiring state migrations, OR confirmed migration code has been added to consumer and/or provider modules +* [ ] confirmed all author checklist items have been addressed +* [ ] reviewed state machine logic +* [ ] reviewed API design and naming +* [ ] reviewed documentation is accurate +* [ ] reviewed tests and test coverage diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 029e4e2a7d..42241f2b1d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,5 +15,15 @@ updates: interval: weekly target-branch: "main" open-pull-requests-limit: 10 + labels: + - dependencies + + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + target-branch: "release/v2.0.x" + # Only allow automated security-related dependency updates on release branches. + open-pull-requests-limit: 0 labels: - dependencies \ No newline at end of file diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml index edff66d593..175bec9545 100644 --- a/.github/workflows/automated-tests.yml +++ b/.github/workflows/automated-tests.yml @@ -24,9 +24,9 @@ jobs: uses: actions/setup-go@v4 with: go-version: "1.19" # The Go version to download (if necessary) and use. - + # - name: Proto Check + # run: make proto-check - name: Unit, integration and difference tests run: go test ./... - - name: E2E tests run: make test-e2e-short diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ae061b147..ab15d52ae0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,7 @@ on: push: branches: - main + - feat/* pull_request: types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f4f80b4863..09a848478a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,13 +2,18 @@ name: "CodeQL" on: push: - branches: [main] + branches: + - main + - feat/* + paths-ignore: - - 'legacy_ibc_testing' + - "legacy_ibc_testing" pull_request: - branches: [main] + branches: + - main + - feat/* paths-ignore: - - 'legacy_ibc_testing' + - "legacy_ibc_testing" schedule: # ┌───────────── minute (0 - 59) # │ ┌───────────── hour (0 - 23) @@ -62,4 +67,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 \ No newline at end of file + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 8675f914f7..87b4ced180 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,4 +1,3 @@ - name: Deploy docs # This job builds and deploys documenation to github pages. # It runs on every push to main with a change in the docs folder. @@ -41,7 +40,7 @@ jobs: make build-docs - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.1 + uses: JamesIves/github-pages-deploy-action@v4.4.2 with: branch: gh-pages folder: ~/output diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index d7b6e640f2..28eba10b41 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -6,6 +6,7 @@ on: branches: - master - main + - feat/* pull_request: permissions: contents: read diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml index e59b4a252b..ddcf2d3594 100644 --- a/.github/workflows/gosec.yml +++ b/.github/workflows/gosec.yml @@ -3,9 +3,11 @@ on: push: branches: - main + - feat/* pull_request: branches: - main + - feat/* jobs: tests: runs-on: ubuntu-latest diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index 9a6f8698de..0fe0e48d81 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@v1.24.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000000..a74b230946 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,4 @@ +{ + "MD036": false, + "MD013": false +} \ No newline at end of file diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000000..7eae0395e1 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,20 @@ +defaults: + actions: + backport: + assignees: + - "{{ author }}" + +queue_rules: + - name: default + conditions: + - "#approved-reviews-by>1" + +pull_request_rules: + - name: Backport patches to the release/v2.0.x branch + conditions: + - base=main + - label=A:backport/v2.0.x + actions: + backport: + branches: + - release/v2.0.x diff --git a/CHANGELOG.md b/CHANGELOG.md index c72d0c9a2f..5960c76238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,126 @@ # CHANGELOG +## [Unreleased] + +Add an entry to the unreleased section whenever merging a PR to main that is not targeted at a specific release. These entries will eventually be included in a release. + +## v.2.0.0 + +Date: June 1st, 2023 + +Unlike prior releases, the ICS `v2.0.0` release will be based on the main branch. `v2.0.0` will contain all the accumulated PRs from the various releases below, along with other PRs that were merged, but not released to production. After `v2.0.0`, we plan to revamp release practices, and how we modularize the repo for consumer/provider. + +Upgrading a provider from `v1.1.0-multiden` to `v2.0.0` will require state migrations. See [migration.go](./x/ccv/provider/keeper/migration.go). See the provider module's `ConsensusVersion` in [module](./x/ccv/provider/module.go) + +Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. See the consumer module's `ConsensusVersion` in [module](./x/ccv/consumer/module.go) + +Some PRs from v2.0.0 may reappear from other releases below. This is due to the fact that ICS v1.1.0 deviates from the commit ordering of the main branch, and other releases thereafter are based on v1.1.0. + +### High level changes included in v2.0.0 + +* MVP for standalone to consumer changeover, see [EPIC](https://github.com/cosmos/interchain-security/issues/756) +* MVP for soft opt out, see [EPIC](https://github.com/cosmos/interchain-security/issues/851) +* Various fixes, critical and non-critical +* Docs updates which should not affect production code + +## Notable PRs included in v2.0.0 + +* (feat!) Add DistributionTransmissionChannel to ConsumerAdditionProposal [#965](https://github.com/cosmos/interchain-security/pull/965) +* (feat/fix) limit vsc matured packets handled per endblocker [#1004](https://github.com/cosmos/interchain-security/pull/1004) +* (fix) cosumer key prefix order to avoid complex migrations [#963](https://github.com/cosmos/interchain-security/pull/963) and [#991](https://github.com/cosmos/interchain-security/pull/991). The latter PR is the proper fix. +* (feat) v1->v2 migrations to accommodate a bugfix having to do with store keys, introduce new params, and deal with consumer genesis state schema changes [#975](https://github.com/cosmos/interchain-security/pull/975) and [#997](https://github.com/cosmos/interchain-security/pull/997) +* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.4.0 to 4.4.2 [#982](https://github.com/cosmos/interchain-security/pull/982) +* (fix) partially revert key assignment type safety PR [#980](https://github.com/cosmos/interchain-security/pull/980) +* (fix) Remove panics on failure to send IBC packets [#876](https://github.com/cosmos/interchain-security/pull/876) +* (fix) Prevent denom DOS [#931](https://github.com/cosmos/interchain-security/pull/931) +* (fix) multisig for assigning consumer key, use json [#916](https://github.com/cosmos/interchain-security/pull/916) +* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.3.0 to 4.4.0 [#902](https://github.com/cosmos/interchain-security/pull/902) +* (feat) Add warnings when provider unbonding is shorter than consumer unbonding [#858](https://github.com/cosmos/interchain-security/pull/858) +* (chore) use go 1.19 [#899](https://github.com/cosmos/interchain-security/pull/899), [#840](https://github.com/cosmos/interchain-security/pull/840) +* (feat) Standalone to consumer changeover - recycle existing transfer channel [#832](https://github.com/cosmos/interchain-security/pull/832) +* (deps) Bump IBC [862](https://github.com/cosmos/interchain-security/pull/862) +* (testing) Add tests for soft opt out [#857](https://github.com/cosmos/interchain-security/pull/857) +* (feat) Standalone to consumer changeover - staking functionalities [#794](https://github.com/cosmos/interchain-security/pull/794) +* (fix) prevent provider from sending VSCPackets with multiple updates for the same validator [#850](https://github.com/cosmos/interchain-security/pull/850) +* (feat) Soft opt out [#833](https://github.com/cosmos/interchain-security/issues/833) +* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) +* (deps) bump sdk to v0.45.15.ics [#805](https://github.com/cosmos/interchain-security/pull/805) +* (refactor) Remove spm module [#812](https://github.com/cosmos/interchain-security/pull/812) +* (feat) Standalone to consumer changeover part 1 [#757](https://github.com/cosmos/interchain-security/pull/757) +* (chore) Swap names of e2e and integration tests [#681](https://github.com/cosmos/interchain-security/pull/681) +* (fix) fix StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802). Also in earlier releases with different commit order! +* (docs) Introduce docs website [#759](https://github.com/cosmos/interchain-security/pull/759) +* (fix) Serialize correct byte prefix for SlashLogKey [#786](https://github.com/cosmos/interchain-security/pull/786) +* (feature) Improve keeper field validation [#766](https://github.com/cosmos/interchain-security/pull/766) +* (docs) Contributing guidelines [#744](https://github.com/cosmos/interchain-security/pull/744) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) +* (fix) Update protos and fix deps [#752](https://github.com/cosmos/interchain-security/pull/752) +* (api) Add consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) +* (feature) New validation for keeper fields [#740](https://github.com/cosmos/interchain-security/pull/740) + +## v1.2.0-multiden + +The first release candidate for a fix built on top of v1.2.0, intended for consumers. This release adds a list of denoms on the consumer that are allowed to be sent to the provider as rewards. This prevents a potential DOS attack that was discovered during the audit of Replicated Security performed by Oak Security and funded by the Cosmos Hub community through Proposal 687. In an effort to move quickly, this release also includes a multisig fix that is effective only for provider. It shouldn't affect the consumer module. + +Note PRs were made in a private security repo. + +[full diff](https://github.com/cosmos/interchain-security/compare/v1.2.0...v1.2.0-multiden-rc0) + +## v1.1.0-multiden + +This release combines two fixes on top of v1.1.0, that we judged were urgent to get onto the Cosmos Hub before the launch of the first ICS consumer chain. This is an emergency release intended for providers. + +The first fix is to enable the use of multisigs and Ledger devices when assigning keys for consumer chains. The second is to prevent a possible DOS vector involving the reward distribution system. + +Note PRs were made in a private security repo. + +[full diff](https://github.com/cosmos/interchain-security/compare/v1.1.0...release/v1.1.0-multiden) + +### Multisig fix + +On April 25th (a week and a half ago), we began receiving reports that validators using multisigs and Ledger devices were getting errors reading Error: unable to resolve type URL /interchain_security.ccv.provider.v1.MsgAssignConsumerKey: tx parse error when attempting to assign consensus keys for consumer chains. + +We quickly narrowed the problem down to issues having to do with using the PubKey type directly in the MsgAssignConsumerKey transaction, and Amino (a deprecated serialization library still used in Ledger devices and multisigs) not being able to handle this. We attempted to fix this with the assistance of the Cosmos-SDK team, but after making no headway for a few days, we decided to simply use a JSON representation of the PubKey in the transaction. This is how it is usually represented anyway. We have verified that this fixes the problem. + +### Distribution fix + +The ICS distribution system works by allowing consumer chains to send rewards to a module address on the provider called the FeePoolAddress. From here they are automatically distributed to all validators and delegators through the distribution system that already exists to distribute staking rewards. The FeePoolAddress is usually blocked so that no tokens can be sent to it, but to enable ICS distribution we had to unblock it. + +We recently realized that unblocking the FeePoolAddress could enable an attacker to send a huge number of different denoms into the distribution system. The distribution system would then attempt to distribute them all, leading to out of memory errors. Fixing a similar attack vector that existed in the distribution system before ICS led us to this realization. + +To fix this problem, we have re-blocked the FeePoolAddress and created a new address called the ConsumerRewardsPool. Consumer chains now send rewards to this new address. There is also a new transaction type called RegisterConsumerRewardDenom. This transaction allows people to register denoms to be used as rewards from consumer chains. It costs 10 Atoms to run this transaction.The Atoms are transferred to the community pool. Only denoms registered with this command are then transferred to the FeePoolAddress and distributed out to delegators and validators. + +## v1.2.1 + +* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) + +## v1.2.0 + +Date: April 13th, 2023 + +* (feat) Soft opt-out [#833](https://github.com/cosmos/interchain-security/pull/833) +* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) +* (chore) bump: sdk v0.45.15-ics [#805](https://github.com/cosmos/interchain-security/pull/805) +* (api) add interchain security consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) + +## v1.1.1 + +* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) + +## v1.1.0 + +Date: March 24th, 2023 + +* (fix) StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802) + ## v1.0.0 Date: February 6th, 2023 -This is the first version of Interchain Security (ICS), also known as _Replicated Security_ (RS). -Replicated Security is a feature which will allow a chain -- referred to as the _provider_ -- to share security with other chains -- referred to as _consumers_. +This is the first version of Interchain Security (ICS), also known as _Replicated Security_ (RS). +Replicated Security is a feature which will allow a chain -- referred to as the _provider_ -- to share security with other chains -- referred to as _consumers_. This means that the provider's validator set will be granted the right to validate consumer chains. The communication between the provider and the consumer chains is done through the IBC protocol over a unique, ordered channel (one for each consumer chain). Thus, RS is an IBC application. @@ -26,9 +141,3 @@ In addition, RS has the following features: - **Key Assignment**: Enables validator operators to use different consensus keys for each consumer chain validator node that they operate. - **Jail Throttling**: Enables the provider to slow down a "worst case scenario" attack where a malicious consumer binary attempts to jail a significant amount (> 2/3) of the voting power, effectively taking control of the provider. - -### Dependencies - -- [ibc-go](https://github.com/cosmos/ibc-go): [v4.2.0](https://github.com/cosmos/ibc-go/blob/release/v4.2.x/CHANGELOG.md) -- [cosmos-sdk](https://github.com/cosmos/cosmos-sdk): [v0.45.12-ics](https://github.com/cosmos/cosmos-sdk/tree/v0.45.13-ics) -- [tendermint](https://github.com/informalsystems/tendermint): [0.34.24](https://github.com/informalsystems/tendermint/tree/v0.34.24) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21fc360d3f..e9a3c092ae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,8 +170,9 @@ Then: 4. Be sure to include a relevant changelog entry in the `Unreleased` section of `CHANGELOG.md` (see file for log format). The entry should be on top of all others changes in the section. PRs must have a category prefix that is based on the type of changes being made (for example, `fix`, `feat`, -`refactor`, `docs`, and so on). The *type* must be included in the PR title as a prefix (for example, -`fix: `). This convention ensures that all changes that are committed to the base branch follow the +`refactor`, `docs`, and so on). The [type](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) +must be included in the PR title as a prefix (for example, `fix: `). +This convention ensures that all changes that are committed to the base branch follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. Additionally, **each PR should only address a single issue**. @@ -179,10 +180,11 @@ Additionally, **each PR should only address a single issue**. ### Pull Request Templates -There are three PR templates. The [default template](./.github/PULL_REQUEST_TEMPLATE.md) is for types `fix`, `feat`, and `refactor`. We also have a [docs template](./.github/PULL_REQUEST_TEMPLATE/docs.md) for documentation changes and an [other template](./.github/PULL_REQUEST_TEMPLATE/other.md) for changes that do not affect production code. When previewing a PR before it has been opened, you can change the template by adding one of the following parameters to the url: +There are three PR templates. The [default template](./.github/PULL_REQUEST_TEMPLATE.md) contains links to the three templates. Please go the the `Preview` tab and select the appropriate sub-template: -* `template=docs.md` -* `template=other.md` +- The [production template](./.github/PULL_REQUEST_TEMPLATE/production.md) is for types `fix`, `feat`, and `refactor`. +- The [docs template](./.github/PULL_REQUEST_TEMPLATE/docs.md) is for documentation changes. +- The [others template](./.github/PULL_REQUEST_TEMPLATE/others.md) is for changes that do not affect production code. ### Requesting Reviews @@ -195,7 +197,7 @@ that you would like early feedback and tagging whoever you would like to receive Codeowners are marked automatically as the reviewers. All PRs require at least two review approvals before they can be merged (one review might be acceptable in -the case of minor changes to [docs](./.github/PULL_REQUEST_TEMPLATE/docs.md) or [other](./.github/PULL_REQUEST_TEMPLATE/other.md) changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible +the case of minor changes to [docs](./.github/PULL_REQUEST_TEMPLATE/docs.md) or [others](./.github/PULL_REQUEST_TEMPLATE/others.md) changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible for all checked items unless they have indicated otherwise by leaving their handle next to specific items. In addition, use the following review explanations: diff --git a/Dockerfile b/Dockerfile index cf10a12cc9..dee88dae7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,17 +31,25 @@ RUN make install # Get Hermes build FROM ghcr.io/informalsystems/hermes:1.4.1 AS hermes-builder +# Get CometMock +FROM informalofftermatt/cometmock:latest as cometmock-builder + +# Get GoRelayer +FROM informalofftermatt/gorelayer:nogas AS gorelayer-builder + FROM --platform=linux/amd64 fedora:36 RUN dnf update -y RUN dnf install -y which iproute iputils procps-ng vim-minimal tmux net-tools htop jq USER root COPY --from=hermes-builder /usr/bin/hermes /usr/local/bin/ +COPY --from=cometmock-builder /usr/local/bin/cometmock /usr/local/bin/cometmock +COPY --from=gorelayer-builder /bin/rly /usr/local/bin/ COPY --from=is-builder /go/bin/interchain-security-pd /usr/local/bin/interchain-security-pd COPY --from=is-builder /go/bin/interchain-security-cd /usr/local/bin/interchain-security-cd COPY --from=is-builder /go/bin/interchain-security-cdd /usr/local/bin/interchain-security-cdd - +COPY --from=is-builder /go/bin/interchain-security-sd /usr/local/bin/interchain-security-sd # Copy in the shell scripts that run the testnet ADD ./tests/e2e/testnet-scripts /testnet-scripts diff --git a/Dockerfile.gaia b/Dockerfile.gaia index a78fc994fd..b9f6ff007f 100644 --- a/Dockerfile.gaia +++ b/Dockerfile.gaia @@ -74,7 +74,7 @@ COPY --from=hermes-builder /usr/bin/hermes /usr/local/bin/ COPY --from=gaia-builder /go/gaia/build/gaiad /usr/local/bin/interchain-security-pd COPY --from=is-builder /go/bin/interchain-security-cd /usr/local/bin/interchain-security-cd COPY --from=is-builder /go/bin/interchain-security-cdd /usr/local/bin/interchain-security-cdd - +COPY --from=is-builder /go/bin/interchain-security-sd /usr/local/bin/interchain-security-sd # Copy in the shell scripts that run the testnet ADD ./tests/e2e/testnet-scripts /testnet-scripts diff --git a/Makefile b/Makefile index 528359a862..69cdfa74be 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ install: go.sum go install $(BUILD_FLAGS) ./cmd/interchain-security-pd go install $(BUILD_FLAGS) ./cmd/interchain-security-cd go install $(BUILD_FLAGS) ./cmd/interchain-security-cdd + go install $(BUILD_FLAGS) ./cmd/interchain-security-sd # run all tests: unit, integration, diff, and E2E test: @@ -105,40 +106,55 @@ $(BUILDDIR)/: ### Protobuf ### ############################################################################### +DOCKER := $(shell which docker) +HTTPS_GIT := https://github.com/cosmos/interchain-security.git + containerProtoVer=0.13.0 containerProtoImage=ghcr.io/cosmos/proto-builder:$(containerProtoVer) -containerProtoGen=cosmos-sdk-proto-gen-$(containerProtoVer) -containerProtoGenSwagger=cosmos-sdk-proto-gen-swagger-$(containerProtoVer) -containerProtoFmt=cosmos-sdk-proto-fmt-$(containerProtoVer) + +protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) + proto-all: proto-format proto-lint proto-gen proto-gen: @echo "Generating Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) \ - sh ./scripts/protocgen.sh; fi + @$(protoImage) sh ./scripts/protocgen.sh; + +proto-check: + @if git diff --quiet; then \ + echo "No files were modified before running 'make proto-gen'."; \ + else \ + echo "Error: Uncommitted changes exist before running 'make proto-gen'. Please commit or stash your changes."; \ + exit 1; \ + fi + @$(MAKE) proto-gen + @if git diff --quiet; then \ + echo "No files were modified after running 'make proto-gen'. Pass!"; \ + else \ + echo "Error: Files were modified after running 'make proto-gen'. Please commit changes to .pb files"; \ + exit 1; \ + fi proto-format: @echo "Formatting Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ - find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi + @$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \; proto-swagger-gen: @echo "Generating Protobuf Swagger" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGenSwagger}$$"; then docker start -a $(containerProtoGenSwagger); else docker run --name $(containerProtoGenSwagger) -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) \ - sh ./scripts/protoc-swagger-gen.sh; fi + @$(protoImage) sh ./scripts/protocgen.sh proto-lint: - @$(DOCKER_BUF) lint --error-format=json + @$(protoImage) buf lint --error-format=json proto-check-breaking: - @$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=main + @$(protoImage) buf breaking --against $(HTTPS_GIT)#branch=main proto-update-deps: @echo "Updating Protobuf dependencies" - $(DOCKER) run --rm -v $(CURDIR)/proto:/workspace --workdir /workspace $(protoImageName) buf mod update + $(protoImage) buf mod update -.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps mocks +.PHONY: proto-all proto-gen proto-format proto-lint proto-check proto-check-breaking proto-update-deps mocks ############################################################################### ### Documentation ### diff --git a/README.md b/README.md index d7e63d11f5..df86648ea4 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,9 @@ [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=cosmos_interchain-security&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=cosmos_interchain-security) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=cosmos_interchain-security&metric=coverage)](https://sonarcloud.io/summary/new_code?id=cosmos_interchain-security) -**interchain-security** houses the code for implementing Interchain Security. The repo is currently a WIP and targetting v1 of Interchain Security. For more details on the Interchain Security protocol, take a look at the [specification](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/README.md). +**interchain-security** contains a working and in-production implementation of the Replicated Security protocol (aka Interchain Security V1). Replicated security is an open sourced IBC application which allows cosmos blockchains to lease their proof-of-stake security to one another. -CCV stands for cross chain validation and refers to the subset of Interchain Security related to the staking and slashing communication between the provider and consumer blockchains. The provider blockchain communicates staking changes to consumer blockchain(s), while the consumer blockchain may communicate slashing evidence to the provider blockchain. - -The code for CCV is housed under [x/ccv](./x/ccv). The `types` folder contains types and related functions that are used by both provider and consumer chains, while the `consumer` module contains the code run by consumer chains and the `provider` module contains the code run by provider chain. +For more details on the Replicated Security protocol, take a look at the [docs](https://cosmos.github.io/interchain-security/) or [technical specification](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/README.md). ## Instructions diff --git a/app/consumer-democracy/ante/forbidden_proposals_ante_test.go b/app/consumer-democracy/ante/forbidden_proposals_ante_test.go index 34b26e4ec0..5c67506e7c 100644 --- a/app/consumer-democracy/ante/forbidden_proposals_ante_test.go +++ b/app/consumer-democracy/ante/forbidden_proposals_ante_test.go @@ -10,8 +10,8 @@ import ( govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - app "github.com/cosmos/interchain-security/app/consumer-democracy" - "github.com/cosmos/interchain-security/app/consumer-democracy/ante" + app "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + "github.com/cosmos/interchain-security/v2/app/consumer-democracy/ante" "github.com/stretchr/testify/require" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" diff --git a/app/consumer-democracy/ante_handler.go b/app/consumer-democracy/ante_handler.go index d4345c7b9d..b031c9fadc 100644 --- a/app/consumer-democracy/ante_handler.go +++ b/app/consumer-democracy/ante_handler.go @@ -1,15 +1,15 @@ package app import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - democracyante "github.com/cosmos/interchain-security/app/consumer-democracy/ante" - consumerante "github.com/cosmos/interchain-security/app/consumer/ante" - ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + democracyante "github.com/cosmos/interchain-security/v2/app/consumer-democracy/ante" + consumerante "github.com/cosmos/interchain-security/v2/app/consumer/ante" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC @@ -23,13 +23,13 @@ type HandlerOptions struct { func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "account keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "bank keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "sign mode handler is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } sigGasConsumer := options.SigGasConsumer diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 4aa85e258c..e72b62c9e5 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -4,7 +4,6 @@ import ( "fmt" "io" stdlog "log" - "net/http" "os" "path/filepath" @@ -16,7 +15,7 @@ import ( consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - appparams "github.com/cosmos/interchain-security/app/params" + appparams "github.com/cosmos/interchain-security/v2/app/params" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" @@ -87,27 +86,25 @@ import ( porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - "github.com/gorilla/mux" - "github.com/rakyll/statik/fs" + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" "github.com/spf13/cast" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - testutil "github.com/cosmos/interchain-security/testutil/integration" - ccvdistr "github.com/cosmos/interchain-security/x/ccv/democracy/distribution" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" + ccvdistr "github.com/cosmos/interchain-security/v2/x/ccv/democracy/distribution" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccvstaking "github.com/cosmos/interchain-security/x/ccv/democracy/staking" + ccvstaking "github.com/cosmos/interchain-security/v2/x/ccv/democracy/staking" gov "github.com/cosmos/cosmos-sdk/x/gov" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - ccvgov "github.com/cosmos/interchain-security/x/ccv/democracy/governance" + ccvgov "github.com/cosmos/interchain-security/v2/x/ccv/democracy/governance" // add mint mint "github.com/cosmos/cosmos-sdk/x/mint" @@ -116,9 +113,9 @@ import ( paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - consumer "github.com/cosmos/interchain-security/x/ccv/consumer" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumer "github.com/cosmos/interchain-security/v2/x/ccv/consumer" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" // unnamed import of statik for swagger UI support _ "github.com/cosmos/cosmos-sdk/client/docs/statik" @@ -126,7 +123,7 @@ import ( const ( AppName = "interchain-security-cd" - upgradeName = "v07-Theta" // arbitrary name, define your own appropriately named upgrade + upgradeName = "sovereign-changeover" // arbitrary name, define your own appropriately named upgrade AccountAddressPrefix = "cosmos" ) @@ -493,7 +490,7 @@ func New( // register slashing module StakingHooks to the consumer keeper app.ConsumerKeeper = *app.ConsumerKeeper.SetHooks(app.SlashingKeeper.Hooks()) - consumerModule := consumer.NewAppModule(app.ConsumerKeeper) + consumerModule := consumer.NewAppModule(app.ConsumerKeeper, app.GetSubspace(consumertypes.ModuleName)) app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, @@ -691,6 +688,8 @@ func New( app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) + // Note this upgrade handler is just an example and may not be exactly what you need to implement. + // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { @@ -709,12 +708,6 @@ func New( // upgrade handler code is application specific. However, as an example, standalone to consumer // changeover chains should utilize customized upgrade handler code similar to below. - // Setting the standalone transfer channel ID is only needed for standalone to consumer changeover chains - // who wish to preserve existing IBC transfer denoms. Here's an example. - // - // Note: This setter needs to execute before the ccv channel handshake is initiated. - app.ConsumerKeeper.SetStandaloneTransferChannelID(ctx, "hardcoded-existing-channel-id") - // TODO: should have a way to read from current node home userHomeDir, err := os.UserHomeDir() if err != nil { @@ -988,17 +981,6 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) { tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) } -// RegisterSwaggerAPI registers swagger route with API Server -func RegisterSwaggerAPI(rtr *mux.Router) { - statikFS, err := fs.New() - if err != nil { - panic(err) - } - - staticServer := http.FileServer(statikFS) - rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) -} - // GetMaccPerms returns a copy of the module account permissions func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) diff --git a/app/consumer-democracy/proposals_whitelisting_test.go b/app/consumer-democracy/proposals_whitelisting_test.go index 1cf5a6e83b..3b8bbdb855 100644 --- a/app/consumer-democracy/proposals_whitelisting_test.go +++ b/app/consumer-democracy/proposals_whitelisting_test.go @@ -3,9 +3,9 @@ package app_test import ( "testing" - appConsumer "github.com/cosmos/interchain-security/app/consumer-democracy" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" "github.com/stretchr/testify/require" ) diff --git a/app/consumer/ante/disabled_modules_ante_test.go b/app/consumer/ante/disabled_modules_ante_test.go index 05f230300b..2eb95e1ddb 100644 --- a/app/consumer/ante/disabled_modules_ante_test.go +++ b/app/consumer/ante/disabled_modules_ante_test.go @@ -8,8 +8,8 @@ import ( evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - "github.com/cosmos/interchain-security/app/consumer/ante" - "github.com/cosmos/interchain-security/app/params" + "github.com/cosmos/interchain-security/v2/app/consumer/ante" + "github.com/cosmos/interchain-security/v2/app/params" "github.com/stretchr/testify/require" ) diff --git a/app/consumer/ante/msg_filter_ante_test.go b/app/consumer/ante/msg_filter_ante_test.go index d315c3c992..7ff11dc10f 100644 --- a/app/consumer/ante/msg_filter_ante_test.go +++ b/app/consumer/ante/msg_filter_ante_test.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - "github.com/cosmos/interchain-security/app/consumer/ante" - "github.com/cosmos/interchain-security/app/params" + "github.com/cosmos/interchain-security/v2/app/consumer/ante" + "github.com/cosmos/interchain-security/v2/app/params" "github.com/stretchr/testify/require" ) diff --git a/app/consumer/ante_handler.go b/app/consumer/ante_handler.go index f4abc86bfd..be33266f8d 100644 --- a/app/consumer/ante_handler.go +++ b/app/consumer/ante_handler.go @@ -1,14 +1,15 @@ package app import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - consumerante "github.com/cosmos/interchain-security/app/consumer/ante" - ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + + consumerante "github.com/cosmos/interchain-security/v2/app/consumer/ante" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC @@ -22,13 +23,13 @@ type HandlerOptions struct { func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "account keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "bank keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "sign mode handler is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } sigGasConsumer := options.SigGasConsumer diff --git a/app/consumer/app.go b/app/consumer/app.go index a63c50304e..34c18bb249 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -4,7 +4,6 @@ import ( "fmt" "io" stdlog "log" - "net/http" "os" "path/filepath" @@ -82,26 +81,24 @@ import ( porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - appparams "github.com/cosmos/interchain-security/app/params" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - "github.com/gorilla/mux" - "github.com/rakyll/statik/fs" + appparams "github.com/cosmos/interchain-security/v2/app/params" + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" "github.com/spf13/cast" tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibcconsumer "github.com/cosmos/interchain-security/x/ccv/consumer" - ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - ibcconsumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + ibcconsumer "github.com/cosmos/interchain-security/v2/x/ccv/consumer" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + ibcconsumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" // unnamed import of statik for swagger UI support _ "github.com/cosmos/cosmos-sdk/client/docs/statik" - testutil "github.com/cosmos/interchain-security/testutil/integration" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" ) const ( AppName = "interchain-security-c" - upgradeName = "v07-Theta" + upgradeName = "ics-v1-to-v2" AccountAddressPrefix = "cosmos" ) @@ -380,7 +377,7 @@ func New( // register slashing module Slashing hooks to the consumer keeper app.ConsumerKeeper = *app.ConsumerKeeper.SetHooks(app.SlashingKeeper.Hooks()) - consumerModule := ibcconsumer.NewAppModule(app.ConsumerKeeper) + consumerModule := ibcconsumer.NewAppModule(app.ConsumerKeeper, app.GetSubspace(ibcconsumertypes.ModuleName)) app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, @@ -553,6 +550,8 @@ func New( app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) + // Note this upgrade handler is just an example and may not be exactly what you need to implement. + // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { @@ -771,11 +770,6 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig // Register grpc query routes. ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) - - // register swagger API from root so that other applications can override easily - if apiConfig.Swagger { - RegisterSwaggerAPI(apiSvr.Router) - } } // RegisterTxService implements the Application.RegisterTxService method. @@ -792,17 +786,6 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) { tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) } -// RegisterSwaggerAPI registers swagger route with API Server -func RegisterSwaggerAPI(rtr *mux.Router) { - statikFS, err := fs.New() - if err != nil { - panic(err) - } - - staticServer := http.FileServer(statikFS) - rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) -} - // GetMaccPerms returns a copy of the module account permissions func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) diff --git a/app/provider/ante_handler.go b/app/provider/ante_handler.go index 4b901f6c49..0a71573b07 100644 --- a/app/provider/ante_handler.go +++ b/app/provider/ante_handler.go @@ -1,10 +1,9 @@ package app import ( - sdkerrors "cosmossdk.io/errors" - + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" @@ -20,13 +19,13 @@ type HandlerOptions struct { func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "account keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "bank keeper is required for AnteHandler") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrorstypes.ErrLogic, "sign mode handler is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } sigGasConsumer := options.SigGasConsumer diff --git a/app/provider/app.go b/app/provider/app.go index b6c3f36dc1..1c73131b63 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -4,7 +4,6 @@ import ( "fmt" "io" stdlog "log" - "net/http" "os" "path/filepath" @@ -15,7 +14,7 @@ import ( autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - appparams "github.com/cosmos/interchain-security/app/params" + appparams "github.com/cosmos/interchain-security/v2/app/params" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" @@ -93,24 +92,23 @@ import ( ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - "github.com/gorilla/mux" - "github.com/rakyll/statik/fs" "github.com/spf13/cast" - ibcprovider "github.com/cosmos/interchain-security/x/ccv/provider" - ibcproviderclient "github.com/cosmos/interchain-security/x/ccv/provider/client" - ibcproviderkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + ibcprovider "github.com/cosmos/interchain-security/v2/x/ccv/provider" + ibcproviderclient "github.com/cosmos/interchain-security/v2/x/ccv/provider/client" + ibcproviderkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" - testutil "github.com/cosmos/interchain-security/testutil/integration" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" // unnamed import of statik for swagger UI support _ "github.com/cosmos/cosmos-sdk/client/docs/statik" @@ -118,7 +116,7 @@ import ( const ( AppName = "interchain-security-p" - upgradeName = "v07-Theta" + upgradeName = "ics-v1-to-v2" AccountAddressPrefix = "cosmos" ) @@ -166,13 +164,14 @@ var ( // module account permissions maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, - minttypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - govtypes.ModuleName: {authtypes.Burner}, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + authtypes.FeeCollectorName: nil, + distrtypes.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + govtypes.ModuleName: {authtypes.Burner}, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + providertypes.ConsumerRewardsPool: nil, } ) @@ -317,12 +316,12 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - // Remove the fee-pool from the group of blocked recipient addresses in bank + // Remove the ConsumerRewardsPool from the group of blocked recipient addresses in bank // this is required for the provider chain to be able to receive tokens from // the consumer chain bankBlockedAddrs := app.ModuleAccountAddrs() delete(bankBlockedAddrs, authtypes.NewModuleAddress( - authtypes.FeeCollectorName).String()) + providertypes.ConsumerRewardsPool).String()) app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, @@ -431,10 +430,12 @@ func New( app.SlashingKeeper, app.AccountKeeper, app.EvidenceKeeper, + app.DistrKeeper, + app.BankKeeper, authtypes.FeeCollectorName, ) - providerModule := ibcprovider.NewAppModule(&app.ProviderKeeper) + providerModule := ibcprovider.NewAppModule(&app.ProviderKeeper, app.GetSubspace(providertypes.ModuleName)) // register the proposal types govRouter := govv1beta1.NewRouter() @@ -637,6 +638,8 @@ func New( app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) + // Note this upgrade handler is just an example and may not be exactly what you need to implement. + // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { @@ -812,6 +815,11 @@ func (app *App) GetTestDistributionKeeper() testutil.TestDistributionKeeper { return app.DistrKeeper } +// GetTestAccountKeeper implements the ProviderApp interface. +func (app *App) GetTestAccountKeeper() testutil.TestAccountKeeper { + return app.AccountKeeper +} + // TestingApp functions // GetBaseApp implements the TestingApp interface. @@ -879,17 +887,6 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) { tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) } -// RegisterSwaggerAPI registers swagger route with API Server -func RegisterSwaggerAPI(rtr *mux.Router) { - statikFS, err := fs.New() - if err != nil { - panic(err) - } - - staticServer := http.FileServer(statikFS) - rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) -} - // GetMaccPerms returns a copy of the module account permissions func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) diff --git a/app/sovereign/ante_handler.go b/app/sovereign/ante_handler.go new file mode 100644 index 0000000000..0a71573b07 --- /dev/null +++ b/app/sovereign/ante_handler.go @@ -0,0 +1,54 @@ +package app + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" +) + +// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC +// channel keeper. +type HandlerOptions struct { + ante.HandlerOptions + + IBCKeeper *ibckeeper.Keeper +} + +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { + if options.AccountKeeper == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") + } + if options.BankKeeper == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") + } + if options.SignModeHandler == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") + } + + sigGasConsumer := options.SigGasConsumer + if sigGasConsumer == nil { + sigGasConsumer = ante.DefaultSigVerificationGasConsumer + } + + anteDecorators := []sdk.AnteDecorator{ + ante.NewSetUpContextDecorator(), + ante.NewExtensionOptionsDecorator(nil), + ante.NewValidateBasicDecorator(), + ante.NewTxTimeoutHeightDecorator(), + ante.NewValidateMemoDecorator(options.AccountKeeper), + ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + // SetPubKeyDecorator must be called before all signature verification decorators + ante.NewSetPubKeyDecorator(options.AccountKeeper), + ante.NewValidateSigCountDecorator(options.AccountKeeper), + ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), + ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + ante.NewIncrementSequenceDecorator(options.AccountKeeper), + ibcante.NewRedundantRelayDecorator(options.IBCKeeper), + } + + return sdk.ChainAnteDecorators(anteDecorators...), nil +} diff --git a/app/sovereign/app.go b/app/sovereign/app.go new file mode 100644 index 0000000000..9c729885f4 --- /dev/null +++ b/app/sovereign/app.go @@ -0,0 +1,872 @@ +package app + +import ( + "fmt" + "io" + stdlog "log" + "os" + "path/filepath" + + appparams "github.com/cosmos/interchain-security/v2/app/params" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/server" + + "github.com/cosmos/cosmos-sdk/server/api" + "github.com/cosmos/cosmos-sdk/server/config" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/std" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + + "github.com/cosmos/cosmos-sdk/x/auth/ante" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/auth/vesting" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/cosmos/cosmos-sdk/x/authz" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" + "github.com/cosmos/cosmos-sdk/x/bank" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/capability" + capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + "github.com/cosmos/cosmos-sdk/x/crisis" + crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + "github.com/cosmos/cosmos-sdk/x/evidence" + evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + "github.com/cosmos/cosmos-sdk/x/feegrant" + feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" + feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" + govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + "github.com/cosmos/cosmos-sdk/x/params" + paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + + dbm "github.com/cometbft/cometbft-db" + abci "github.com/cometbft/cometbft/abci/types" + tmjson "github.com/cometbft/cometbft/libs/json" + "github.com/cometbft/cometbft/libs/log" + tmos "github.com/cometbft/cometbft/libs/os" + "github.com/cosmos/cosmos-sdk/x/slashing" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/upgrade" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v7/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + "github.com/spf13/cast" + + sdkdistr "github.com/cosmos/cosmos-sdk/x/distribution" + distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" + + sdkstaking "github.com/cosmos/cosmos-sdk/x/staking" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + + sdkgov "github.com/cosmos/cosmos-sdk/x/gov" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + // add mint + mint "github.com/cosmos/cosmos-sdk/x/mint" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + + paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" +) + +const ( + AppName = "interchain-security-s" + upgradeName = "v07-Theta" // arbitrary name, define your own appropriately named upgrade + AccountAddressPrefix = "cosmos" +) + +var ( + // DefaultNodeHome default home directories for the application daemon + DefaultNodeHome string + + // ModuleBasics defines the module BasicManager is in charge of setting up basic, + // non-dependant module elements, such as codec registration + // and genesis verification. + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + genutil.AppModuleBasic{}, + bank.AppModuleBasic{}, + capability.AppModuleBasic{}, + sdkstaking.AppModuleBasic{}, + mint.AppModuleBasic{}, + sdkdistr.AppModuleBasic{}, + sdkgov.NewAppModuleBasic( + []govclient.ProposalHandler{ + paramsclient.ProposalHandler, + upgradeclient.LegacyProposalHandler, + upgradeclient.LegacyCancelProposalHandler, + }, + ), + params.AppModuleBasic{}, + crisis.AppModuleBasic{}, + slashing.AppModuleBasic{}, + feegrantmodule.AppModuleBasic{}, + authzmodule.AppModuleBasic{}, + ibc.AppModuleBasic{}, + upgrade.AppModuleBasic{}, + evidence.AppModuleBasic{}, + transfer.AppModuleBasic{}, + vesting.AppModuleBasic{}, + ) + + // module account permissions + maccPerms = map[string][]string{ + authtypes.FeeCollectorName: nil, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + distrtypes.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + govtypes.ModuleName: {authtypes.Burner}, + } +) + +var ( + _ runtime.AppI = (*App)(nil) + _ servertypes.Application = (*App)(nil) + _ ibctesting.TestingApp = (*App)(nil) +) + +// App extends an ABCI application, but with most of its parameters exported. +// They are exported for convenience in creating helper functions, as object +// capabilities aren't needed for testing. +type App struct { // nolint: golint + *baseapp.BaseApp + legacyAmino *codec.LegacyAmino + appCodec codec.Codec + interfaceRegistry types.InterfaceRegistry + txConfig client.TxConfig + + // keys to access the substores + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey + + // keepers + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.Keeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + + DistrKeeper distrkeeper.Keeper + + ConsensusParamsKeeper consensusparamkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + AuthzKeeper authzkeeper.Keeper + + // make scoped keepers public for test purposes + ScopedIBCKeeper capabilitykeeper.ScopedKeeper + ScopedTransferKeeper capabilitykeeper.ScopedKeeper + + // the module manager + MM *module.Manager + + // simulation manager + sm *module.SimulationManager + configurator module.Configurator +} + +func init() { + userHomeDir, err := os.UserHomeDir() + if err != nil { + stdlog.Println("Failed to get home dir %2", err) + } + + DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) +} + +// New returns a reference to an initialized App. +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *App { + encodingConfig := makeEncodingConfig() + + appCodec := encodingConfig.Codec + legacyAmino := encodingConfig.Amino + interfaceRegistry := encodingConfig.InterfaceRegistry + + bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) + bApp.SetCommitMultiStoreTracer(traceStore) + bApp.SetVersion(version.Version) + bApp.SetInterfaceRegistry(interfaceRegistry) + + keys := sdk.NewKVStoreKeys( + authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, + capabilitytypes.StoreKey, authzkeeper.StoreKey, + ) + tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + + app := &App{ + BaseApp: bApp, + legacyAmino: legacyAmino, + appCodec: appCodec, + interfaceRegistry: interfaceRegistry, + keys: keys, + tkeys: tkeys, + memKeys: memKeys, + } + + app.ParamsKeeper = initParamsKeeper( + appCodec, + legacyAmino, + keys[paramstypes.StoreKey], + tkeys[paramstypes.TStoreKey], + ) + + // set the BaseApp's parameter store + // upgradetypes.StoreKey -> maybe consensusparamtypes.StoreKey (package consensusparamtypes ("github.com/cosmos/cosmos-sdk/x/consensus/types") + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) + bApp.SetParamStore(&app.ConsensusParamsKeeper) + + // add capability keeper and ScopeToModule for ibc module + app.CapabilityKeeper = capabilitykeeper.NewKeeper( + appCodec, + keys[capabilitytypes.StoreKey], + memKeys[capabilitytypes.MemStoreKey], + ) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + app.CapabilityKeeper.Seal() + + // add keepers + app.AccountKeeper = authkeeper.NewAccountKeeper( + appCodec, + keys[authtypes.StoreKey], + authtypes.ProtoBaseAccount, + maccPerms, + AccountAddressPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + bankBlockedAddrs := app.ModuleAccountAddrs() + + app.BankKeeper = bankkeeper.NewBaseKeeper( + appCodec, + keys[banktypes.StoreKey], + app.AccountKeeper, + bankBlockedAddrs, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + app.AuthzKeeper = authzkeeper.NewKeeper( + keys[authzkeeper.StoreKey], + appCodec, + app.BaseApp.MsgServiceRouter(), + app.AccountKeeper, + ) + app.FeeGrantKeeper = feegrantkeeper.NewKeeper( + appCodec, + keys[feegrant.StoreKey], + app.AccountKeeper, + ) + + app.StakingKeeper = *stakingkeeper.NewKeeper( + appCodec, + keys[stakingtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.MintKeeper = mintkeeper.NewKeeper( + appCodec, + keys[minttypes.StoreKey], + app.StakingKeeper, + app.AccountKeeper, + app.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + legacyAmino, + keys[slashingtypes.StoreKey], + app.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + keys[distrtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) + app.CrisisKeeper = *crisiskeeper.NewKeeper( + appCodec, + keys[crisistypes.StoreKey], + invCheckPeriod, + app.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // get skipUpgradeHeights from the app options + skipUpgradeHeights := map[int64]bool{} + for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { + skipUpgradeHeights[int64(h)] = true + } + homePath := cast.ToString(appOpts.Get(flags.FlagHome)) + app.UpgradeKeeper = *upgradekeeper.NewKeeper( + skipUpgradeHeights, + keys[upgradetypes.StoreKey], + appCodec, + homePath, + app.BaseApp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + app.StakingKeeper.SetHooks( + stakingtypes.NewMultiStakingHooks( + app.DistrKeeper.Hooks(), + app.SlashingKeeper.Hooks(), + ), + ) + + // register the proposal types + sdkgovRouter := govv1beta1.NewRouter() + sdkgovRouter. + AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.UpgradeKeeper)) + govConfig := govtypes.DefaultConfig() + + app.GovKeeper = *govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.GovKeeper.SetLegacyRouter(sdkgovRouter) + + app.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + keys[ibchost.StoreKey], + app.GetSubspace(ibchost.ModuleName), + &app.StakingKeeper, + app.UpgradeKeeper, + scopedIBCKeeper, + ) + + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + legacyAmino, + keys[slashingtypes.StoreKey], + app.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.TransferKeeper = ibctransferkeeper.NewKeeper( + appCodec, + keys[ibctransfertypes.StoreKey], + app.GetSubspace(ibctransfertypes.ModuleName), + app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, + app.AccountKeeper, + app.BankKeeper, + scopedTransferKeeper, + ) + transferModule := transfer.NewAppModule(app.TransferKeeper) + ibcmodule := transfer.NewIBCModule(app.TransferKeeper) + + // create static IBC router, add transfer route, then set and seal it + ibcRouter := porttypes.NewRouter() + ibcRouter.AddRoute(ibctransfertypes.ModuleName, ibcmodule) + app.IBCKeeper.SetRouter(ibcRouter) + + // create evidence keeper with router + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, + keys[evidencetypes.StoreKey], + &app.StakingKeeper, + app.SlashingKeeper, + ) + + app.EvidenceKeeper = *evidenceKeeper + + skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)) + + // NOTE: Any module instantiated in the module manager that is later modified + // must be passed by reference here. + app.MM = module.NewManager( + genutil.NewAppModule( + app.AccountKeeper, + app.StakingKeeper, + app.BaseApp.DeliverTx, + encodingConfig.TxConfig, + ), + auth.NewAppModule(appCodec, app.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), + vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), + crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + sdkgov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + sdkdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + sdkstaking.NewAppModule(appCodec, &app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + upgrade.NewAppModule(&app.UpgradeKeeper), + evidence.NewAppModule(app.EvidenceKeeper), + params.NewAppModule(app.ParamsKeeper), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + ibc.NewAppModule(app.IBCKeeper), + transferModule, + ) + + app.MM.SetOrderBeginBlockers( + upgradetypes.ModuleName, + capabilitytypes.ModuleName, + minttypes.ModuleName, + distrtypes.ModuleName, + slashingtypes.ModuleName, + evidencetypes.ModuleName, + stakingtypes.ModuleName, + authtypes.ModuleName, + banktypes.ModuleName, + govtypes.ModuleName, + crisistypes.ModuleName, + authz.ModuleName, + feegrant.ModuleName, + paramstypes.ModuleName, + genutiltypes.ModuleName, + vestingtypes.ModuleName, + ibctransfertypes.ModuleName, + ibchost.ModuleName, + ) + app.MM.SetOrderEndBlockers( + crisistypes.ModuleName, + govtypes.ModuleName, + stakingtypes.ModuleName, + capabilitytypes.ModuleName, + authtypes.ModuleName, + banktypes.ModuleName, + distrtypes.ModuleName, + slashingtypes.ModuleName, + minttypes.ModuleName, + evidencetypes.ModuleName, + authz.ModuleName, + feegrant.ModuleName, + paramstypes.ModuleName, + genutiltypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + ibctransfertypes.ModuleName, + ibchost.ModuleName, + ) + + // NOTE: The genutils module must occur after staking so that pools are + // properly initialized with tokens from genesis accounts. + // NOTE: The genutils module must also occur after auth so that it can access the params from auth. + // NOTE: Capability module must occur first so that it can initialize any capabilities + // so that other modules that want to create or claim capabilities afterwards in InitChain + // can do so safely. + app.MM.SetOrderInitGenesis( + capabilitytypes.ModuleName, + authtypes.ModuleName, + banktypes.ModuleName, + distrtypes.ModuleName, + stakingtypes.ModuleName, + slashingtypes.ModuleName, + govtypes.ModuleName, + minttypes.ModuleName, + crisistypes.ModuleName, + evidencetypes.ModuleName, + authz.ModuleName, + feegrant.ModuleName, + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + genutiltypes.ModuleName, + ibchost.ModuleName, + ibctransfertypes.ModuleName, + ) + + app.MM.RegisterInvariants(&app.CrisisKeeper) + + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.MM.RegisterServices(app.configurator) + + // initialize stores + app.MountKVStores(keys) + app.MountTransientStores(tkeys) + app.MountMemoryStores(memKeys) + + anteHandler, err := NewAnteHandler( + HandlerOptions{ + HandlerOptions: ante.HandlerOptions{ + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + FeegrantKeeper: app.FeeGrantKeeper, + SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + }, + IBCKeeper: app.IBCKeeper, + }, + ) + if err != nil { + panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + } + app.SetAnteHandler(anteHandler) + + app.SetInitChainer(app.InitChainer) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + + app.UpgradeKeeper.SetUpgradeHandler( + upgradeName, + func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + + fromVM := make(map[string]uint64) + + for moduleName := range app.MM.Modules { + m := app.MM.Modules[moduleName] + if module, ok := m.(module.HasConsensusVersion); ok { + fromVM[moduleName] = module.ConsensusVersion() + } + } + + ctx.Logger().Info("start to run module migrations...") + + return app.MM.RunMigrations(ctx, app.configurator, fromVM) + }, + ) + + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + panic(fmt.Sprintf("failed to read upgrade info from disk %s", err)) + } + + if upgradeInfo.Name == upgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := storetypes.StoreUpgrades{} + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } + + if loadLatest { + if err := app.LoadLatestVersion(); err != nil { + tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err)) + } + } + + app.ScopedIBCKeeper = scopedIBCKeeper + app.ScopedTransferKeeper = scopedTransferKeeper + + return app +} + +// Name returns the name of the App +func (app *App) Name() string { return app.BaseApp.Name() } + +// BeginBlocker application updates every begin block +func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + return app.MM.BeginBlock(ctx, req) +} + +// EndBlocker application updates every end block +func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + return app.MM.EndBlock(ctx, req) +} + +// InitChainer application update at chain initialization +func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + var genesisState GenesisState + if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + panic(err) + } + + app.UpgradeKeeper.SetModuleVersionMap(ctx, app.MM.GetVersionMap()) + return app.MM.InitGenesis(ctx, app.appCodec, genesisState) +} + +// LoadHeight loads a particular height +func (app *App) LoadHeight(height int64) error { + return app.LoadVersion(height) +} + +// ModuleAccountAddrs returns all the app's module account addresses. +func (app *App) ModuleAccountAddrs() map[string]bool { + modAccAddrs := make(map[string]bool) + for acc := range maccPerms { + modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true + } + + return modAccAddrs +} + +// LegacyAmino returns App's amino codec. +// +// NOTE: This is solely to be used for testing purposes as it may be desirable +// for modules to register their own custom testing types. +func (app *App) LegacyAmino() *codec.LegacyAmino { + return app.legacyAmino +} + +// AppCodec returns the app codec. +// +// NOTE: This is solely to be used for testing purposes as it may be desirable +// for modules to register their own custom testing types. +func (app *App) AppCodec() codec.Codec { + return app.appCodec +} + +// InterfaceRegistry returns the InterfaceRegistry +func (app *App) InterfaceRegistry() types.InterfaceRegistry { + return app.interfaceRegistry +} + +// GetKey returns the KVStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetKey(storeKey string) *storetypes.KVStoreKey { + return app.keys[storeKey] +} + +// GetTKey returns the TransientStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetTKey(storeKey string) *storetypes.TransientStoreKey { + return app.tkeys[storeKey] +} + +// GetMemKey returns the MemStoreKey for the provided mem key. +// +// NOTE: This is solely used for testing purposes. +func (app *App) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { + return app.memKeys[storeKey] +} + +// GetSubspace returns a param subspace for a given module name. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { + subspace, _ := app.ParamsKeeper.GetSubspace(moduleName) + return subspace +} + +// SimulationManager implements the SimulationApp interface +func (app *App) SimulationManager() *module.SimulationManager { + return app.sm +} + +func (app *App) GetTestBankKeeper() testutil.TestBankKeeper { + return app.BankKeeper +} + +func (app *App) GetTestAccountKeeper() testutil.TestAccountKeeper { + return app.AccountKeeper +} + +func (app *App) GetTestSlashingKeeper() testutil.TestSlashingKeeper { + return app.SlashingKeeper +} + +func (app *App) GetTestEvidenceKeeper() testutil.TestEvidenceKeeper { + return app.EvidenceKeeper +} + +func (app *App) GetTestStakingKeeper() testutil.TestStakingKeeper { + return app.StakingKeeper +} + +func (app *App) GetTestDistributionKeeper() testutil.TestDistributionKeeper { + return app.DistrKeeper +} + +func (app *App) GetTestMintKeeper() testutil.TestMintKeeper { + return app.MintKeeper +} + +func (app *App) GetTestGovKeeper() testutil.TestGovKeeper { + return app.GovKeeper +} + +// TestingApp functions + +// GetBaseApp implements the TestingApp interface. +func (app *App) GetBaseApp() *baseapp.BaseApp { + return app.BaseApp +} + +// GetStakingKeeper implements the TestingApp interface. +func (app *App) GetStakingKeeper() ibctestingcore.StakingKeeper { + return app.StakingKeeper +} + +// GetIBCKeeper implements the TestingApp interface. +func (app *App) GetIBCKeeper() *ibckeeper.Keeper { + return app.IBCKeeper +} + +// GetScopedIBCKeeper implements the TestingApp interface. +func (app *App) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { + return app.ScopedIBCKeeper +} + +// GetTxConfig implements the TestingApp interface. +func (app *App) GetTxConfig() client.TxConfig { + return app.txConfig +} + +// TxConfig returns SimApp's TxConfig +func (app *App) TxConfig() client.TxConfig { + return app.txConfig +} + +// RegisterAPIRoutes registers all application module routes with the provided +// API server. +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { + clientCtx := apiSvr.ClientCtx + // Register new tx routes from grpc-gateway. + authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register new tendermint queries routes from grpc-gateway. + tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register node gRPC service for grpc-gateway. + nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // Register legacy and grpc-gateway routes for all modules. + ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) +} + +func (app *App) RegisterNodeService(clientCtx client.Context) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +} + +// RegisterTxService implements the Application.RegisterTxService method. +func (app *App) RegisterTxService(clientCtx client.Context) { + authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) +} + +// RegisterTendermintService implements the Application.RegisterTendermintService method. +func (app *App) RegisterTendermintService(clientCtx client.Context) { + tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) +} + +// GetMaccPerms returns a copy of the module account permissions +func GetMaccPerms() map[string][]string { + dupMaccPerms := make(map[string][]string) + for k, v := range maccPerms { + dupMaccPerms[k] = v + } + return dupMaccPerms +} + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { + paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) + + paramsKeeper.Subspace(authtypes.ModuleName) + paramsKeeper.Subspace(banktypes.ModuleName) + paramsKeeper.Subspace(stakingtypes.ModuleName) + paramsKeeper.Subspace(minttypes.ModuleName) + paramsKeeper.Subspace(distrtypes.ModuleName) + paramsKeeper.Subspace(slashingtypes.ModuleName) + paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(sdkgov.ProvideKeyTable()) + paramsKeeper.Subspace(crisistypes.ModuleName) + paramsKeeper.Subspace(ibctransfertypes.ModuleName) + paramsKeeper.Subspace(ibchost.ModuleName) + + return paramsKeeper +} + +// MakeTestEncodingConfig creates an EncodingConfig for testing. This function +// should be used only in tests or when creating a new app instance (NewApp*()). +// App user shouldn't create new codecs - use the app.AppCodec instead. +// [DEPRECATED] +// func MakeTestEncodingConfig() appparams.EncodingConfig { +// encodingConfig := appparams.MakeTestEncodingConfig() +// std.RegisterLegacyAminoCodec(encodingConfig.Amino) +// std.RegisterInterfaces(encodingConfig.InterfaceRegistry) +// ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) +// ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) +// return encodingConfig +// } + +func MakeTestEncodingConfig() appparams.EncodingConfig { + encodingConfig := appparams.MakeTestEncodingConfig() + std.RegisterLegacyAminoCodec(encodingConfig.Amino) + std.RegisterInterfaces(encodingConfig.InterfaceRegistry) + ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) + ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) + return encodingConfig +} + +func makeEncodingConfig() appparams.EncodingConfig { + encodingConfig := appparams.MakeTestEncodingConfig() + std.RegisterLegacyAminoCodec(encodingConfig.Amino) + std.RegisterInterfaces(encodingConfig.InterfaceRegistry) + ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) + ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) + return encodingConfig +} diff --git a/app/sovereign/export.go b/app/sovereign/export.go new file mode 100644 index 0000000000..770d9b540f --- /dev/null +++ b/app/sovereign/export.go @@ -0,0 +1,196 @@ +package app + +import ( + "encoding/json" + "log" + + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/staking" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// ExportAppStateAndValidators exports the state of the application for a genesis +// file. +func (app *App) ExportAppStateAndValidators( + forZeroHeight bool, jailAllowedAddrs, modulesToExport []string, +) (servertypes.ExportedApp, error) { + // as if they could withdraw from the start of the next block + ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + + // We export at last height + 1, because that's the height at which + // Tendermint will start InitChain. + height := app.LastBlockHeight() + 1 + if forZeroHeight { + height = 0 + app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) + } + + genState := app.MM.ExportGenesis(ctx, app.appCodec) + appState, err := json.MarshalIndent(genState, "", " ") + if err != nil { + return servertypes.ExportedApp{}, err + } + + validators, err := staking.WriteValidators(ctx, &app.StakingKeeper) + if err != nil { + return servertypes.ExportedApp{}, err + } + return servertypes.ExportedApp{ + AppState: appState, + Validators: validators, + Height: height, + ConsensusParams: app.BaseApp.GetConsensusParams(ctx), + }, nil +} + +// prepare for fresh start at zero height +// NOTE zero height genesis is a temporary feature which will be deprecated +// +// in favour of export at a block height +func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { + applyAllowedAddrs := false + + // check if there is a allowed address list + if len(jailAllowedAddrs) > 0 { + applyAllowedAddrs = true + } + + allowedAddrsMap := make(map[string]bool) + + for _, addr := range jailAllowedAddrs { + _, err := sdk.ValAddressFromBech32(addr) + if err != nil { + log.Fatal(err) + } + allowedAddrsMap[addr] = true + } + + /* Just to be safe, assert the invariants on current state. */ + app.CrisisKeeper.AssertInvariants(ctx) + + /* Handle fee distribution state. */ + + // withdraw all validator commission + app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) + if err != nil { + panic(err) + } + return false + }) + + // withdraw all delegator rewards + dels := app.StakingKeeper.GetAllDelegations(ctx) + for _, delegation := range dels { + _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) + if err != nil { + panic(err) + } + } + + // clear validator slash events + app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) + + // clear validator historical rewards + app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + + // set context height to zero + height := ctx.BlockHeight() + ctx = ctx.WithBlockHeight(0) + + // reinitialize all validators + app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + // donate any unwithdrawn outstanding reward fraction tokens to the community pool + scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + feePool := app.DistrKeeper.GetFeePool(ctx) + feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) + app.DistrKeeper.SetFeePool(ctx, feePool) + + err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + if err != nil { + panic(err) + } + return false + }) + + // reinitialize all delegations + for _, del := range dels { + err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + if err != nil { + panic(err) + } + err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + if err != nil { + panic(err) + } + } + + // reset context height + ctx = ctx.WithBlockHeight(height) + + /* Handle staking state. */ + + // iterate through redelegations, reset creation height + app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { + for i := range red.Entries { + red.Entries[i].CreationHeight = 0 + } + app.StakingKeeper.SetRedelegation(ctx, red) + return false + }) + + // iterate through unbonding delegations, reset creation height + app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { + for i := range ubd.Entries { + ubd.Entries[i].CreationHeight = 0 + } + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + return false + }) + + // Iterate through validators by power descending, reset bond heights, and + // update bond intra-tx counters. + store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) + iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + counter := int16(0) + + for ; iter.Valid(); iter.Next() { + addr := sdk.ValAddress(iter.Key()[1:]) + validator, found := app.StakingKeeper.GetValidator(ctx, addr) + if !found { + panic("expected validator, not found") + } + + validator.UnbondingHeight = 0 + if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { + validator.Jailed = true + } + + app.StakingKeeper.SetValidator(ctx, validator) + counter++ + } + + if err := iter.Close(); err != nil { + panic(err) + } + + if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil { + panic(err) + } + + /* Handle slashing state. */ + + // reset start height on signing infos + app.SlashingKeeper.IterateValidatorSigningInfos( + ctx, + func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { + info.StartHeight = 0 + app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) + return false + }, + ) +} diff --git a/app/sovereign/genesis.go b/app/sovereign/genesis.go new file mode 100644 index 0000000000..5bf0c1da80 --- /dev/null +++ b/app/sovereign/genesis.go @@ -0,0 +1,21 @@ +package app + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" +) + +// The genesis state of the blockchain is represented here as a map of raw json +// messages key'd by a identifier string. +// The identifier is used to determine which module genesis information belongs +// to so it may be appropriately routed during init chain. +// Within this application default genesis information is retrieved from +// the ModuleBasicManager which populates json from each BasicModule +// object provided to it during init. +type GenesisState map[string]json.RawMessage + +// NewDefaultGenesisState generates the default state for the application. +func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { + return ModuleBasics.DefaultGenesis(cdc) +} diff --git a/cmd/interchain-security-cd/cmd/root.go b/cmd/interchain-security-cd/cmd/root.go index 8acbc28e91..10af60f25f 100644 --- a/cmd/interchain-security-cd/cmd/root.go +++ b/cmd/interchain-security-cd/cmd/root.go @@ -28,8 +28,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - consumer "github.com/cosmos/interchain-security/app/consumer" - "github.com/cosmos/interchain-security/app/params" + consumer "github.com/cosmos/interchain-security/v2/app/consumer" + "github.com/cosmos/interchain-security/v2/app/params" ) // NewRootCmd creates a new root command for simd. It is called once in the diff --git a/cmd/interchain-security-cd/main.go b/cmd/interchain-security-cd/main.go index 4985a79d99..589869cd43 100644 --- a/cmd/interchain-security-cd/main.go +++ b/cmd/interchain-security-cd/main.go @@ -5,8 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - app "github.com/cosmos/interchain-security/app/consumer" - "github.com/cosmos/interchain-security/cmd/interchain-security-cd/cmd" + app "github.com/cosmos/interchain-security/v2/app/consumer" + "github.com/cosmos/interchain-security/v2/cmd/interchain-security-cd/cmd" ) func main() { diff --git a/cmd/interchain-security-cdd/cmd/root.go b/cmd/interchain-security-cdd/cmd/root.go index 6dab71c8c1..615bdf499c 100644 --- a/cmd/interchain-security-cdd/cmd/root.go +++ b/cmd/interchain-security-cdd/cmd/root.go @@ -28,8 +28,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - cdd "github.com/cosmos/interchain-security/app/consumer-democracy" - "github.com/cosmos/interchain-security/app/params" + + cdd "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + "github.com/cosmos/interchain-security/v2/app/params" ) // NewRootCmd creates a new root command for simd. It is called once in the diff --git a/cmd/interchain-security-cdd/main.go b/cmd/interchain-security-cdd/main.go index 6072f8ea5e..f209f0046a 100644 --- a/cmd/interchain-security-cdd/main.go +++ b/cmd/interchain-security-cdd/main.go @@ -5,8 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - app "github.com/cosmos/interchain-security/app/consumer-democracy" - "github.com/cosmos/interchain-security/cmd/interchain-security-cdd/cmd" + app "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + "github.com/cosmos/interchain-security/v2/cmd/interchain-security-cdd/cmd" ) func main() { diff --git a/cmd/interchain-security-pd/cmd/root.go b/cmd/interchain-security-pd/cmd/root.go index 808a7a326d..e480acfc34 100644 --- a/cmd/interchain-security-pd/cmd/root.go +++ b/cmd/interchain-security-pd/cmd/root.go @@ -28,9 +28,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - "github.com/cosmos/interchain-security/app/params" - - providerApp "github.com/cosmos/interchain-security/app/provider" + "github.com/cosmos/interchain-security/v2/app/params" + providerApp "github.com/cosmos/interchain-security/v2/app/provider" ) // NewRootCmd creates a new root command for simd. It is called once in the diff --git a/cmd/interchain-security-pd/main.go b/cmd/interchain-security-pd/main.go index 5c4b7ff631..d39371adc1 100644 --- a/cmd/interchain-security-pd/main.go +++ b/cmd/interchain-security-pd/main.go @@ -5,8 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - app "github.com/cosmos/interchain-security/app/provider" - "github.com/cosmos/interchain-security/cmd/interchain-security-pd/cmd" + app "github.com/cosmos/interchain-security/v2/app/provider" + "github.com/cosmos/interchain-security/v2/cmd/interchain-security-pd/cmd" ) func main() { diff --git a/cmd/interchain-security-sd/cmd/root.go b/cmd/interchain-security-sd/cmd/root.go new file mode 100644 index 0000000000..955da62464 --- /dev/null +++ b/cmd/interchain-security-sd/cmd/root.go @@ -0,0 +1,307 @@ +package cmd + +import ( + "errors" + "io" + "os" + + dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" + serverconfig "github.com/cosmos/cosmos-sdk/server/config" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + rosettaCmd "cosmossdk.io/tools/rosetta/cmd" + tmcfg "github.com/cometbft/cometbft/config" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/config" + "github.com/cosmos/cosmos-sdk/client/debug" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/pruning" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/server" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/crisis" + genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + "github.com/cosmos/interchain-security/v2/app/params" + sovereignApp "github.com/cosmos/interchain-security/v2/app/sovereign" +) + +// NewRootCmd creates a new root command for simd. It is called once in the +// main function. +func NewRootCmd() *cobra.Command { + // we "pre"-instantiate the application for getting the injected/configured encoding configuration + tempApp := sovereignApp.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(sovereignApp.DefaultNodeHome)) + encodingConfig := params.EncodingConfig{ + InterfaceRegistry: tempApp.InterfaceRegistry(), + Codec: tempApp.AppCodec(), + TxConfig: tempApp.TxConfig(), + Amino: tempApp.LegacyAmino(), + } + + initClientCtx := client.Context{}. + WithCodec(encodingConfig.Codec). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithInput(os.Stdin). + WithAccountRetriever(types.AccountRetriever{}). + WithHomeDir(sovereignApp.DefaultNodeHome). + WithViper("") // In simapp, we don't use any prefix for env variables. + + rootCmd := &cobra.Command{ + Use: "simd", + Short: "simulation app", + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { + // set the default command outputs + cmd.SetOut(cmd.OutOrStdout()) + cmd.SetErr(cmd.ErrOrStderr()) + + initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags()) + if err != nil { + return err + } + + initClientCtx, err = config.ReadFromClientConfig(initClientCtx) + if err != nil { + return err + } + + if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { + return err + } + + customAppTemplate, customAppConfig := initAppConfig() + customTMConfig := initTendermintConfig() + + return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) + }, + } + + initRootCmd(rootCmd, encodingConfig) + + return rootCmd +} + +// initTendermintConfig helps to override default Tendermint Config values. +// return tmcfg.DefaultConfig if no custom configuration is required for the application. +func initTendermintConfig() *tmcfg.Config { + cfg := tmcfg.DefaultConfig() + + // these values put a higher strain on node memory + // cfg.P2P.MaxNumInboundPeers = 100 + // cfg.P2P.MaxNumOutboundPeers = 40 + + return cfg +} + +func txCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + DisableFlagParsing: false, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + authcmd.GetSignCommand(), + authcmd.GetSignBatchCommand(), + authcmd.GetMultiSignCommand(), + authcmd.GetMultiSignBatchCmd(), + authcmd.GetValidateSignaturesCommand(), + authcmd.GetBroadcastCommand(), + authcmd.GetEncodeCommand(), + authcmd.GetDecodeCommand(), + authcmd.GetAuxToFeeCommand(), + ) + + sovereignApp.ModuleBasics.AddTxCommands(cmd) + + return cmd +} + +// initAppConfig helps to override default appConfig template and configs. +// return "", nil if no custom configuration is required for the application. +func initAppConfig() (string, interface{}) { + // The following code snippet is just for reference. + + // WASMConfig defines configuration for the wasm module. + type WASMConfig struct { + // This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries + QueryGasLimit uint64 `mapstructure:"query_gas_limit"` + + // Address defines the gRPC-web server to listen on + LruSize uint64 `mapstructure:"lru_size"` + } + + type CustomAppConfig struct { + serverconfig.Config + + WASM WASMConfig `mapstructure:"wasm"` + } + + // Optionally allow the chain developer to overwrite the SDK's default + // server config. + srvCfg := serverconfig.DefaultConfig() + // The SDK's default minimum gas price is set to "" (empty value) inside + // app.toml. If left empty by validators, the node will halt on startup. + // However, the chain developer can set a default app.toml value for their + // validators here. + // + // In summary: + // - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their + // own app.toml config, + // - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their + // own app.toml to override, or use this default value. + // + // In simapp, we set the min gas prices to 0. + srvCfg.MinGasPrices = "0stake" + // srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default + + customAppConfig := CustomAppConfig{ + Config: *srvCfg, + WASM: WASMConfig{ + LruSize: 1, + QueryGasLimit: 300000, + }, + } + + customAppTemplate := serverconfig.DefaultConfigTemplate + ` +[wasm] +# This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries +query_gas_limit = 300000 +# This is the number of wasm vm instances we keep cached in memory for speed-up +# Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally +lru_size = 0` + + return customAppTemplate, customAppConfig +} + +func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { + cfg := sdk.GetConfig() + cfg.Seal() + + rootCmd.AddCommand( + genutilcli.InitCmd(sovereignApp.ModuleBasics, sovereignApp.DefaultNodeHome), + debug.Cmd(), + config.Cmd(), + pruning.PruningCmd(newApp), + ) + + server.AddCommands(rootCmd, sovereignApp.DefaultNodeHome, newApp, appExport, addModuleInitFlags) + + // add keybase, auxiliary RPC, query, genesis, and tx child commands + rootCmd.AddCommand( + rpc.StatusCommand(), + genesisCommand(encodingConfig), + queryCommand(), + txCommand(), + keys.Commands(sovereignApp.DefaultNodeHome), + ) + + // add rosetta + rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) +} + +// newApp is an appCreator +// newApp creates the application +func newApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + appOpts servertypes.AppOptions, +) servertypes.Application { + baseappOptions := server.DefaultBaseappOptions(appOpts) + + return sovereignApp.New( + logger, db, traceStore, true, + appOpts, + baseappOptions..., + ) +} + +// appExport creates a new simapp (optionally at a given height) and exports state. +func appExport( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + height int64, + forZeroHeight bool, + jailAllowedAddrs []string, + appOpts servertypes.AppOptions, + modulesToExport []string, +) (servertypes.ExportedApp, error) { + var simApp *sovereignApp.App + + // this check is necessary as we use the flag in x/upgrade. + // we can exit more gracefully by checking the flag here. + homePath, ok := appOpts.Get(flags.FlagHome).(string) + if !ok || homePath == "" { + return servertypes.ExportedApp{}, errors.New("application home not set") + } + + viperAppOpts, ok := appOpts.(*viper.Viper) + if !ok { + return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper") + } + + // overwrite the FlagInvCheckPeriod + viperAppOpts.Set(server.FlagInvCheckPeriod, 1) + appOpts = viperAppOpts + + if height != -1 { + simApp = sovereignApp.New(logger, db, traceStore, false, appOpts) + + if err := simApp.LoadHeight(height); err != nil { + return servertypes.ExportedApp{}, err + } + } else { + simApp = sovereignApp.New(logger, db, traceStore, true, appOpts) + } + + return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) +} + +func addModuleInitFlags(startCmd *cobra.Command) { + crisis.AddModuleInitFlags(startCmd) +} + +// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter +func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { + cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, sovereignApp.ModuleBasics, sovereignApp.DefaultNodeHome) + for _, sub_cmd := range cmds { + cmd.AddCommand(sub_cmd) + } + return cmd +} + +func queryCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + DisableFlagParsing: false, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + authcmd.GetAccountCmd(), + rpc.ValidatorCommand(), + rpc.BlockCommand(), + authcmd.QueryTxsByEventsCmd(), + authcmd.QueryTxCmd(), + authcmd.GetEncodeCommand(), + authcmd.GetDecodeCommand(), + ) + + sovereignApp.ModuleBasics.AddQueryCommands(cmd) + + return cmd +} diff --git a/cmd/interchain-security-sd/main.go b/cmd/interchain-security-sd/main.go new file mode 100644 index 0000000000..42675b10d2 --- /dev/null +++ b/cmd/interchain-security-sd/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "os" + + "github.com/cosmos/cosmos-sdk/server" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + app "github.com/cosmos/interchain-security/v2/app/sovereign" + "github.com/cosmos/interchain-security/v2/cmd/interchain-security-sd/cmd" +) + +func main() { + rootCmd := cmd.NewRootCmd() + + if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { + switch e := err.(type) { + case server.ErrorCode: + os.Exit(e.Code) + + default: + os.Exit(1) + } + } +} diff --git a/docs/docs/adrs/adr-004-denom-dos-fixes b/docs/docs/adrs/adr-004-denom-dos-fixes new file mode 100644 index 0000000000..7ca260f4f6 --- /dev/null +++ b/docs/docs/adrs/adr-004-denom-dos-fixes @@ -0,0 +1,53 @@ +--- +sidebar_position: 2 +title: ADR Template +--- +# ADR 004: Denom DOS fixes + +## Changelog +* 5/9/2023: ADR created + +## Status + +Accepted + +## Context + +The provider and consumer modules are vulnerable to similar issues involving an attacker sending millions of denoms to certain addresses and causing the chain to halt. This ADR outlines both fixes since they are similar. Both fixes involve processing only denoms that are on a whitelist to avoid iterating over millions of junk denoms but have different requirements and are implemented in different ways. + +## Decision + +### Provider + +- Put the distribution module's FeePoolAddress back on the blocklist so that it cannot receive funds from users. +- Create a new address called ConsumerRewardPool and unblock it, allowing funds to be sent to it. +- Create a set of strings in the store for allowed ConsumerRewardDenoms. +- Create an endpoint called RegisterConsumerRewardDenom which deducts a fee from the sender's account, sends it to the community pool and adds a string to the ConsumerRewardDenoms set. +- Create a parameter called ConsumerRewardDenomRegistrationFee which determines the fee which is charged to register a consumer reward denom in the step above. +- Create a function called TransferRewardsToFeeCollector which gets the entire ConsumerRewardDenoms set from the store, iterates over it, and for each entry: + - Gets the balance of this denom for the ConsumerRewardPool account + - Sends the entire balance out to the FeePoolAddress using SendCoinsFromModuleToModule which is not affected by the blocklist. +- Run TransferRewardsToFeeCollector in the endblock + +Now, nobody can send millions of junk denoms to the FeePoolAddress because it is on the block list. If they send millions of junk denoms to the ConsumerRewardPool, this does not matter because all balances are not iterated over, only those which are in the ConsumerRewardDenoms set. + +We also add a new tx: register-consumer-reward-denom, and a new query: registered-consumer-reward-denoms + +### Consumer + +- Create a new param RewardDenoms with a list of strings +- Create a new param ProviderRewardDenoms with a list of strings +- Create a function AllowedRewardDenoms which iterates over ProviderRewardDenoms and converts each denom to its ibc-prefixed denom using the provider chain's ibc channel information, then concatenates the RewardDenoms list and returns the combined list of allowed denoms. +- In SendRewardsToProvider, instead of iterating over the balances of all denoms in the ToSendToProvider address, iterate over AllowedRewardDenoms + +Now, if somebody sends millions of junk denoms to ToSendToProvider, they will not be iterated over. Only the RewardDenoms and ProviderRewardDenoms will be iterated over. Since we do not require this feature to be permissionless on the consumer, the registration fee process is not needed. + +## Consequences + +### Positive + +- Denom DOS is no longer possible on either provider or consumer. + +### Negative + +- Consumer chain teams must pay a fee to register a denom for distribution on the provider, and add some extra parameters in their genesis file. diff --git a/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md b/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md new file mode 100644 index 0000000000..bf3a761704 --- /dev/null +++ b/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md @@ -0,0 +1,93 @@ +--- +sidebar_position: 2 +title: ADR Template +--- +# ADR 007: Pause validator unbonding during equivocation proposal + +## Changelog +* 2023-05-16: Initial Draft + +## Status + +Proposed + +## Context + +Currently, if an equivocation slashing proposal is created after more than one +week has passed since the equivocation, it is possible that the validator in +question could unbond and get away without being slashed, since the unbonding +period is 3 weeks, and the voting period is 2 weeks. For this reason, it might +be good to pause unbondings for validators named in an equivocation slashing +proposal until the proposal's voting period is over. + +## Decision + +### How + +Pausing the unbonding period is already possible thanks to the changes in the +`staking` module of the cosmos-sdk: +- `stakingKeeper.PutUnbondingOnHold` pauses an unbonding period +- `stakingKeeper.UnbondingCanComplete` unpauses an unbonding period + +These methods use a reference counter under the hood, that gets incremented +every time `PutUnbondingOnHold` is called, and decreased when +`UnbondingCanComplete` is called instead. A specific unbonding is considered +fully unpaused when its underlying reference counter reaches 0. Therefore, as +long as we safeguard consistency - i.e. we make sure we eventually decrement +the reference counter for each time we have incremented it - we can safely use +this existing mechanism without conflicts with the *Completion of Unbonding +Operations* system. + +### When pause + +The unbonding period (if there is any unbonding) should be paused once an +equivocation proposal enters the voting period. For that, the `gov` module's +hook `AfterProposalDeposit` can be used. + +If the hook is triggered with a an equivocation proposal in voting period, then +for each equivocation of the proposal, the unbonding operations of the related +validator that were initiated after the equivocation block time must be paused +- i.e. the underlying reference counter has to be increased. + +Note that even after the voting period has started, a proposal can receive +additional deposits. The hook is triggered however at arrival of a deposit, so +a check to verify that the proposal is not already in voting period is +required. + +### When unpause + +We can use a `gov` module's hook also here and it is +`AfterProposalVotingPeriodEnded`. + +If the hook is triggered with an equivocation proposal, then for each +associated equivocation, the unbonding operations of the related validator that +were initiated between the equivocation block time and the start of the +proposal voting period must be unpaused - i.e. decrease the underlying +reference counter - regardless of the proposal outcome. + +## Consequences + +### Positive + +- Validators subject to an equivocation proposal cannot finish unbonding + their tokens before the end of the voting period. + +### Negative + +- A malicious consumer chain could forge slash packets enabling submission of + an equivocation proposal on the provider chain, resulting in the freezing of + validator's unbondings for an undeterminated amount of time. +- Misbehavior on a consumer chain can potentially go unpunished, if no one + submits an equivocation proposal in time, or if the proposal doesn't pass. + +### Neutral + +- This feature can't be used for social slashing, because an equivocation + proposal is only accepted if there's a slash log for the related + validator(s), meaning the consumer chain has reported the equivocation to + the provider chain. + +## References + +* https://github.com/cosmos/interchain-security/issues/747 +* https://github.com/cosmos/interchain-security/pull/791 diff --git a/docs/docs/adrs/adr-008-throttle-retries.md b/docs/docs/adrs/adr-008-throttle-retries.md new file mode 100644 index 0000000000..a8f0d250ce --- /dev/null +++ b/docs/docs/adrs/adr-008-throttle-retries.md @@ -0,0 +1,105 @@ +--- +sidebar_position: 7 +title: Throttle with retries +--- + +## ADR 008: Throttle with retries + +## Changelog + +* 6/9/23: Initial draft + +## Status + +Accepted + +## Context + +For context on why the throttling mechanism exists, see [ADR 002](./adr-002-throttle.md). + +Note the terms slash throttling and jail throttling are synonymous, since in replicated security a `SlashPacket` simply jails a validator for downtime infractions. + +Currently the throttling mechanism is designed so that provider logic (slash meter, etc.) dictates how many slash packets can be handled over time. Throttled slash packets are persisted on the provider, leading to multiple possible issues. Namely: + +* If slash or vsc matured packets are actually throttled/queued on the provider, state can grow and potentially lead to a DoS attack. We have short term solutions around this, but overall they come with their own weaknesses. See [#594](https://github.com/cosmos/interchain-security/issues/594). +* If a jailing attack described in [ADR 002](adr-002-throttle.md) were actually to be carried out with the current throttling design, we'd likely have to halt the provider, and perform an emergency upgrade and/or migration to clear the queues of slash packets that were deemed to be malicious. Alternatively, validators would just have to _tough it out_ and wait for the queues to clear, during which all/most validators would be jailed. Right after being jailed, vals would have to unjail themselves promptly to ensure safety. The synchronous coordination required to maintain safety in such a scenario is not ideal. + +So what's the solution? We can improve the throttling mechanism to instead queue/persist relevant data on each consumer, and have consumers retry slash requests as needed. + +## Decision + +### Consumer changes + +Note the consumer already queues up both slash and vsc matured packets via `AppendPendingPacket`. Those packets are dequeued every endblock in `SendPackets` and sent to the provider. + +Instead, we will now introduce the following logic on endblock: + +* Slash packets will always be sent to the provider once they're at the head of the queue. However, once sent, the consumer will not send any trailing vsc matured packets from the queue until the provider responds with an ack that the slash packet has been handled (ie. val was jailed). That is, slash packets block the sending of trailing vsc matured packets in the consumer queue. +* If two slash packets are at the head of the queue, the consumer will send the first slash packet, and then wait for a success ack from the provider before sending the second slash packet. This seems like it'd simplify implementation. +* VSC matured packets at the head of the queue (ie. NOT trailing a slash packet) can be sent immediately, and do not block any other packets in the queue, since the provider always handles them immediately. + +To prevent the provider from having to keep track of what slash packets have been rejected, the consumer will have to retry the sending of slash packets over some period of time. This can be achieved with an on-chain consumer param. The suggested param value would probably be 1/2 of the provider's `SlashMeterReplenishmentPeriod`, although it doesn't matter too much as long as the param value is sane. + +Note to prevent weird edge case behavior, a retry would not be attempted until either a success ack or failure ack has been recv from the provider. + +With the behavior described, we maintain very similar behavior to the current throttling mechanism regarding the timing that slash and vsc matured packets are handled on the provider. Obviously the queueing and blocking logic is moved, and the two chains would have to send more messages between one another (only in the case the throttling mechanism is triggered). + +In the normal case, when no or a few slash packets are being sent, the VSCMaturedPackets will not be delayed, and hence unbonding will not be delayed. + +### Provider changes + +The main change needed for the provider is the removal of queuing logic for slash and vsc matured packets upon being received. + +Instead, the provider will consult the slash meter to determine if a slash packet can be handled immediately. If not, the provider will return an ack message to the consumer communicating that the slash packet could not be handled, and needs to be sent again in the future (retried). + +VSCMatured packets will always be handled immediately upon being received by the provider. + +Note [spec](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing). Specifically the section on _VSC Maturity and Slashing Order_. Previously the onus was on the provider to maintain this property via queuing packets and handling them FIFO. + +Now this property will be maintained by the consumer sending packets in the correct order, and blocking the sending of VSCMatured packets as needed. Then, the ordered IBC channel will ensure that Slash/VSCMatured packets are received in the correct order on the provider. + +The provider's main responsibility regarding throttling will now be to determine if a recv slash packet can be handled via slash meter etc., and appropriately ack to the sending consumer. + +### Why the provider can handle VSCMatured packets immediately + +First we answer, what does a VSCMatured packet communicate to the provider? A VSCMatured packet communicates that a VSC has been applied to a consumer long enough that infractions committed on the consumer could have been submitted. + +If the consumer is following the queuing/blocking protocol described. No bad behavior occurs, `VSC Maturity and Slashing Order` property is maintained. + +If a consumer sends VSCMatured packets too leniently: The consumer is malicious and sending duplicate vsc matured packets, or sending the packets sooner than the ccv protocol specifies. In this scenario, the provider needs to handle vsc matured packets immediately to prevent DOS, state bloat, or other issues. The only possible negative outcome is that the malicious consumer may not be able to jail a validator who should have been jailed. The malicious behavior only creates a negative outcome for the chain that is being malicious. + +If a consumer blocks the sending of VSCMatured packets: The consumer is malicious and blocking vsc matured packets that should have been sent. This will block unbonding only up until the VSC timeout period has elapsed. At that time, the consumer is removed. Again the malicious behavior only creates a negative outcome for the chain that is being malicious. + +### Splitting of PRs + +We could split this feature into two PRs, one affecting the consumer and one affecting the provider, along with a third PR which could setup a clever way to upgrade the provider in multiple steps, ensuring that queued slash packets at upgrade time are handled properly. + +## Consequences + +* Consumers will now have to manage their own queues, and retry logic. +* Consumers still aren't trustless, but the provider is now less susceptible to mismanaged or malicious consumers. +* Recovering from the "jailing attack" is more elegant. +* Some issues like [#1001](https://github.com/cosmos/interchain-security/issues/1001) will now be handled implicitly by the improved throttling mechanism. +* Slash and vsc matured packets can be handled immediately once recv by the provider if the slash meter allows. +* In general, we reduce the amount of computation that happens in the provider end-blocker. + +### Positive + +* We no longer have to reason about a "global queue" and a "chain specific queue", and keeping those all in-sync. Now slash and vsc matured packet queuing is handled on each consumer individually. +* Due to the above, the throttling protocol becomes less complex overall. +* We no longer have to worry about throttle related DoS attack on the provider, since no queuing exists on the provider. + +### Negative + +* Increased number of IBC packets being relayed anytime throttling logic is triggered. +* Consumer complexity increases, since consumers now have manage queuing themselves, and implement packet retry logic. + +### Neutral + +* Core throttling logic on the provider remains unchanged, ie. slash meter, replenishment cycles, etc. + +## References + +* [EPIC](https://github.com/cosmos/interchain-security/issues/713) tracking the changes proposed by this ADR +* [ADR 002: Jail Throttling](./adr-002-throttle.md) +* [#594](https://github.com/cosmos/interchain-security/issues/594) \ No newline at end of file diff --git a/docs/docs/adrs/intro.md b/docs/docs/adrs/intro.md index aa6b7781c9..bdd59ad20b 100644 --- a/docs/docs/adrs/intro.md +++ b/docs/docs/adrs/intro.md @@ -34,4 +34,7 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov | ------ | ----------- | ------ | | [001](./adr-001-key-assignment.md) | Consumer chain key assignment | Accepted, Implemented | | [002](./adr-002-throttle.md) | Jail Throttling | Accepted, Implemented | -| [003](./adr-003-equivocation-gov-proposal.md) | Equivocation governance proposal | Accepted, Implemented +| [003](./adr-003-equivocation-gov-proposal.md) | Equivocation governance proposal | Accepted, Implemented | +| [004](./adr-004-denom-dos-fixes) | Denom DOS fixes | Accepted, Implemented | +| [007](./adr-007-pause-unbonding-on-eqv-prop.md) | Pause validator unbonding during equivocation proposal | Proposed | +| [008](./adr-008-throttle-retries.md) | Throttle with retries | Accepted, In-progress | diff --git a/docs/docs/consumer-development/onboarding.md b/docs/docs/consumer-development/onboarding.md index faa2969e63..89c5f32dc5 100644 --- a/docs/docs/consumer-development/onboarding.md +++ b/docs/docs/consumer-development/onboarding.md @@ -91,6 +91,13 @@ Example of a consumer chain addition proposal. // This param is a part of the cosmos sdk staking module. In the case of // a ccv enabled consumer chain, the ccv module acts as the staking module. "historical_entries": 10000, + // The ID of a token transfer channel used for the Reward Distribution + // sub-protocol. If DistributionTransmissionChannel == "", a new transfer + // channel is created on top of the same connection as the CCV channel. + // Note that transfer_channel_id is the ID of the channel end on the consumer chain. + // it is most relevant for chains performing a sovereign to consumer changeover + // in order to maintan the existing ibc transfer channel + "distribution_transmission_channel": "channel-123" } ``` diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index 9285baa62b..a34160ecf4 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -43,6 +43,9 @@ Minimal example: "historical_entries": 10000, "genesis_hash": "d86d756e10118e66e6805e9cc476949da2e750098fcc7634fd0cc77f57a0b2b0", "binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1" + // relevant for chains performing a sovereign to consumer changeover + // in order to maintan the existing ibc transfer channel + "distribution_transmission_channel": "channel-123" } ``` More examples can be found in the replicated security testnet repository [here](https://github.com/cosmos/testnets/blob/master/replicated-security/baryon-1/proposal-baryon-1.json) and [here](https://github.com/cosmos/testnets/blob/master/replicated-security/noble-1/start-proposal-noble-1.json). diff --git a/docs/docs/features/reward-distribution.md b/docs/docs/features/reward-distribution.md index 122eab5ad9..31b3f9e54e 100644 --- a/docs/docs/features/reward-distribution.md +++ b/docs/docs/features/reward-distribution.md @@ -12,6 +12,21 @@ The distributed reward tokens are IBC tokens and therefore cannot be staked on t Sending and distributing rewards from consumer chains to provider chain is handled by the `Reward Distribution` sub-protocol. +## Note +The ICS distribution system works by allowing consumer chains to send rewards to a module address on the provider called the `ConsumerRewardsPool`. +There is a new transaction type called `RegisterConsumerRewardDenom`. This transaction allows consumer chains to register denoms to be used as consumer chain rewards on the provider. +The cost to register a denom is configurable (`ConsumerRewardDenomRegistrationFee` chain param) and the full amount of this fee is transferred to the community pool of the provider chain. Only denoms registered through this transaction are then transferred from the `ConsumerRewardsPool` to the `FeePoolAddress`, to be distributed out to delegators and validators. + +### Instructions for adding a denom +The transaction must be carried out on the provider chain. Please use the `ibc/*` denom trace format. + +:::tip +``` +# reward denoms must be registered on the provider chain (gaia in this example) +gaiad tx provider register-consumer-reward-denom ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9 --from mykey +``` +::: + ## Parameters :::tip The following chain parameters dictate consumer chain distribution amount and frequency. @@ -21,12 +36,12 @@ They are set at consumer genesis and `blocks_per_distribution_transmission`, `co ### `consumer_redistribution_fraction` -The fraction of tokens sent from consumer to provider during distribution events. The fraction is a string representing a decimal number. For example "0.75" would represent 75%. +The fraction of tokens allocated to the consumer redistribution address during distribution events. The fraction is a string representing a decimal number. For example "0.75" would represent 75%. :::tip Example: -With `consumer_redistribution_fraction` set to `0.75` the consumer chain would send 75% of its block rewards and accumulated fees to the consumer chain and the remaining 25% to the provider chain every `n` blocks where `n == blocks_per_distribution_transmission`. +With `consumer_redistribution_fraction` set to `0.75` the consumer chain would send 75% of its block rewards and accumulated fees to the consumer redistribution address, and the remaining 25% to the provider chain every `n` blocks where `n == blocks_per_distribution_transmission`. ::: ### `blocks_per_distribution_transmission` diff --git a/docs/docs/validators/overview.md b/docs/docs/validators/overview.md index 5a670f0780..35ce56cdb3 100644 --- a/docs/docs/validators/overview.md +++ b/docs/docs/validators/overview.md @@ -14,7 +14,7 @@ Once a `ConsumerAdditionProposal` passes, validators need to prepare to run the Provider chain and consumer chains represent standalone chains that only share the validator set ie. the same validator operators are tasked with running all chains. :::info -To validate a consumer chain and be eligible for rewards validators are required to be in the active set of the provider chain (first 175 validators for Cosmos Hub). +To validate a consumer chain and be eligible for rewards validators are required to be in the active set of the provider chain (first 180 validators for Cosmos Hub). ::: ## Startup sequence overview diff --git a/docs/src/css/base.css b/docs/src/css/base.css index e6d485266f..bdc9f13c4a 100644 --- a/docs/src/css/base.css +++ b/docs/src/css/base.css @@ -9,7 +9,6 @@ -webkit-font-feature-settings: 'kern', 'liga', 'calt', 'zero' 0; text-size-adjust: 100%; -moz-osx-font-smoothing: grayscale; - font-smoothing: antialiased; font-variant-ligatures: contextual common-ligatures; font-kerning: normal; text-rendering: optimizeLegibility; diff --git a/go.mod b/go.mod index d641d4ce4d..412298c7ae 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ -module github.com/cosmos/interchain-security +module github.com/cosmos/interchain-security/v2 go 1.19 require ( + cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.8.0 @@ -12,11 +13,11 @@ require ( github.com/cosmos/ics23/go v0.10.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/gorilla/mux v1.8.0 + github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/kylelemons/godebug v1.1.0 github.com/oxyno-zeta/gomock-extra-matcher v1.1.0 - github.com/rakyll/statik v0.1.7 + github.com/rakyll/statik v0.1.7 // indirect github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.2 @@ -40,7 +41,6 @@ require ( cosmossdk.io/api v0.3.1 cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/tools/rosetta v0.2.1 filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -146,7 +146,6 @@ require ( github.com/spf13/afero v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect @@ -172,5 +171,7 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) +require github.com/spf13/viper v1.15.0 + // following versions might cause unexpected behavior replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 diff --git a/legacy_ibc_testing/simapp/test_helpers.go b/legacy_ibc_testing/simapp/test_helpers.go index 91846ab674..2d11af5790 100644 --- a/legacy_ibc_testing/simapp/test_helpers.go +++ b/legacy_ibc_testing/simapp/test_helpers.go @@ -18,7 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" - "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp/helpers" + "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp/helpers" ) /* diff --git a/legacy_ibc_testing/testing/app.go b/legacy_ibc_testing/testing/app.go index 792316ca1e..ce4e32c90f 100644 --- a/legacy_ibc_testing/testing/app.go +++ b/legacy_ibc_testing/testing/app.go @@ -6,7 +6,7 @@ import ( "time" "cosmossdk.io/math" - "github.com/cosmos/interchain-security/legacy_ibc_testing/core" + "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" abci "github.com/cometbft/cometbft/abci/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -26,8 +26,8 @@ import ( "github.com/cosmos/ibc-go/v7/modules/core/keeper" - "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) /* diff --git a/legacy_ibc_testing/testing/chain.go b/legacy_ibc_testing/testing/chain.go index 48b6c21bd4..c037ca43c8 100644 --- a/legacy_ibc_testing/testing/chain.go +++ b/legacy_ibc_testing/testing/chain.go @@ -6,7 +6,7 @@ import ( "testing" "time" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -34,8 +34,9 @@ import ( "github.com/cosmos/ibc-go/v7/modules/core/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" "github.com/cosmos/ibc-go/v7/testing/mock" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" + + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" ) /* @@ -455,7 +456,7 @@ func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterpa // NextValidatorsHash tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1)) if !ok { - return nil, sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) + return nil, errorsmod.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) } } // inject trusted fields into last header diff --git a/proto/interchain_security/ccv/consumer/v1/consumer.proto b/proto/interchain_security/ccv/consumer/v1/consumer.proto index 3ee887c22b..1487e579a8 100644 --- a/proto/interchain_security/ccv/consumer/v1/consumer.proto +++ b/proto/interchain_security/ccv/consumer/v1/consumer.proto @@ -3,7 +3,7 @@ package interchain_security.ccv.consumer.v1; import "interchain_security/ccv/v1/ccv.proto"; -option go_package = "github.com/cosmos/interchain-security/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; @@ -32,11 +32,11 @@ message Params { string provider_fee_pool_addr_str = 4; // Sent CCV related IBC packets will timeout after this duration google.protobuf.Duration ccv_timeout_period = 5 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // Sent transfer related IBC packets will timeout after this duration google.protobuf.Duration transfer_timeout_period = 6 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // The fraction of tokens allocated to the consumer redistribution address // during distribution events. The fraction is a string representing a @@ -44,19 +44,28 @@ message Params { string consumer_redistribution_fraction = 7; // The number of historical info entries to persist in store. - // This param is a part of the cosmos sdk staking module. In the case of + // This param is a part of the cosmos sdk staking module. In the case of // a ccv enabled consumer chain, the ccv module acts as the staking module. int64 historical_entries = 8; // Unbonding period for the consumer, // which should be smaller than that of the provider in general. google.protobuf.Duration unbonding_period = 9 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For example, a - // value of 0.05 means that the validators in the bottom 5% of the set can opt out + // can opt out of running the consumer chain without being punished. For + // example, a value of 0.05 means that the validators in the bottom 5% of the + // set can opt out string soft_opt_out_threshold = 10; + + // Reward denoms. These are the denominations which are allowed to be sent to + // the provider as rewards. + repeated string reward_denoms = 11; + + // Provider-originated reward denoms. These are denoms coming from the + // provider which are allowed to be used as rewards. e.g. "uatom" + repeated string provider_reward_denoms = 12; } // LastTransmissionBlockHeight is the last time validator holding @@ -77,5 +86,6 @@ message CrossChainValidator { // MaturingVSCPacket contains the maturing time of a received VSCPacket message MaturingVSCPacket { uint64 vscId = 1; - google.protobuf.Timestamp maturity_time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp maturity_time = 2 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto index 043556fee3..739ac2798e 100644 --- a/proto/interchain_security/ccv/consumer/v1/genesis.proto +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types"; import "interchain_security/ccv/v1/ccv.proto"; import "interchain_security/ccv/consumer/v1/consumer.proto"; @@ -15,16 +15,18 @@ import "gogoproto/gogo.proto"; // GenesisState defines the CCV consumer chain genesis state message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; - string provider_client_id = 2; // empty for a new chain, filled in on restart. - string provider_channel_id = 3; // empty for a new chain, filled in on restart. - bool new_chain = 4; // true for new chain GenesisState, false for chain restart. + string provider_client_id = 2; // empty for a new chain, filled in on restart. + string provider_channel_id = + 3; // empty for a new chain, filled in on restart. + bool new_chain = + 4; // true for new chain GenesisState, false for chain restart. // ProviderClientState filled in on new chain, nil on restart. ibc.lightclients.tendermint.v1.ClientState provider_client_state = 5; // ProviderConsensusState filled in on new chain, nil on restart. ibc.lightclients.tendermint.v1.ConsensusState provider_consensus_state = 6; // MaturingPackets nil on new chain, filled in on restart. - repeated interchain_security.ccv.consumer.v1.MaturingVSCPacket maturing_packets = 7 - [ (gogoproto.nullable) = false ]; + repeated interchain_security.ccv.consumer.v1.MaturingVSCPacket + maturing_packets = 7 [ (gogoproto.nullable) = false ]; // InitialValset filled in on new chain and on restart. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 8 [ (gogoproto.nullable) = false ]; @@ -34,16 +36,17 @@ message GenesisState { // OutstandingDowntimes nil on new chain, filled in on restart. repeated OutstandingDowntime outstanding_downtime_slashing = 10 [ (gogoproto.nullable) = false ]; - // PendingConsumerPackets nil on new chain, filled in on restart. - interchain_security.ccv.v1.ConsumerPacketDataList pending_consumer_packets = 11 - [ (gogoproto.nullable) = false ]; + // PendingConsumerPackets nil on new chain, filled in on restart. + interchain_security.ccv.v1.ConsumerPacketDataList pending_consumer_packets = + 11 [ (gogoproto.nullable) = false ]; // LastTransmissionBlockHeight nil on new chain, filled in on restart. - interchain_security.ccv.consumer.v1.LastTransmissionBlockHeight last_transmission_block_height = 12 - [ (gogoproto.nullable) = false ]; - bool preCCV = 13; // flag indicating whether the consumer CCV module starts in pre-CCV state + interchain_security.ccv.consumer.v1.LastTransmissionBlockHeight + last_transmission_block_height = 12 [ (gogoproto.nullable) = false ]; + bool preCCV = 13; // flag indicating whether the consumer CCV module starts in + // pre-CCV state } -// HeightValsetUpdateID defines the genesis information for the mapping +// HeightValsetUpdateID defines the genesis information for the mapping // of each block height to a valset update id message HeightToValsetUpdateID { uint64 height = 1; diff --git a/proto/interchain_security/ccv/consumer/v1/query.proto b/proto/interchain_security/ccv/consumer/v1/query.proto index 2bcf6b4d50..b5576b57fe 100644 --- a/proto/interchain_security/ccv/consumer/v1/query.proto +++ b/proto/interchain_security/ccv/consumer/v1/query.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; @@ -39,10 +39,10 @@ message NextFeeDistributionEstimate { string toConsumer = 7; } -message QueryNextFeeDistributionEstimateRequest { } +message QueryNextFeeDistributionEstimateRequest {} message QueryNextFeeDistributionEstimateResponse { - NextFeeDistributionEstimate data = 1; + NextFeeDistributionEstimate data = 1; } message QueryParamsRequest {} @@ -50,5 +50,5 @@ message QueryParamsRequest {} // QueryParamsResponse is response type for the Query/Params RPC method. message QueryParamsResponse { // params holds all the parameters of this module. - Params params = 1 [(gogoproto.nullable) = false]; + Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/provider/v1/genesis.proto b/proto/interchain_security/ccv/provider/v1/genesis.proto index 3859f6b7d0..e1c241413b 100644 --- a/proto/interchain_security/ccv/provider/v1/genesis.proto +++ b/proto/interchain_security/ccv/provider/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/provider/types"; import "gogoproto/gogo.proto"; import "interchain_security/ccv/v1/ccv.proto"; @@ -11,41 +11,39 @@ import "interchain_security/ccv/consumer/v1/consumer.proto"; import "interchain_security/ccv/consumer/v1/genesis.proto"; import "tendermint/crypto/keys.proto"; - // GenesisState defines the CCV provider chain genesis state message GenesisState { // strictly positive and set to 1 (DefaultValsetUpdateID) for a new chain - uint64 valset_update_id = 1; + uint64 valset_update_id = 1; // empty for a new chain - repeated ConsumerState consumer_states = 2 [ + repeated ConsumerState consumer_states = 2 [ (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"consumer_states\"" ]; // empty for a new chain repeated interchain_security.ccv.provider.v1.UnbondingOp unbonding_ops = 3 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; // empty for a new chain interchain_security.ccv.v1.MaturedUnbondingOps mature_unbonding_ops = 4; - // empty for a new chain + // empty for a new chain repeated ValsetUpdateIdToHeight valset_update_id_to_height = 5 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; // empty for a new chain repeated ConsumerAdditionProposal consumer_addition_proposals = 6 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; // empty for a new chain repeated ConsumerRemovalProposal consumer_removal_proposals = 7 - [ (gogoproto.nullable) = false ]; - Params params = 8 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; + Params params = 8 [ (gogoproto.nullable) = false ]; // empty for a new chain repeated ValidatorConsumerPubKey validator_consumer_pubkeys = 9 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; // empty for a new chain repeated ValidatorByConsumerAddr validators_by_consumer_addr = 10 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; // empty for a new chain repeated ConsumerAddrsToPrune consumer_addrs_to_prune = 11 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; } // consumer chain @@ -60,19 +58,21 @@ message ConsumerState { uint64 initial_height = 4; // ConsumerGenesis defines the initial consumer chain genesis states interchain_security.ccv.consumer.v1.GenesisState consumer_genesis = 5 - [ (gogoproto.nullable) = false ]; - // PendingValsetChanges defines the pending validator set changes for the consumer chain - repeated interchain_security.ccv.v1.ValidatorSetChangePacketData pending_valset_changes = 6 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; + // PendingValsetChanges defines the pending validator set changes for the + // consumer chain + repeated interchain_security.ccv.v1.ValidatorSetChangePacketData + pending_valset_changes = 6 [ (gogoproto.nullable) = false ]; repeated string slash_downtime_ack = 7; - // UnbondingOpsIndex defines the unbonding operations waiting on this consumer chain - repeated interchain_security.ccv.provider.v1.VscUnbondingOps unbonding_ops_index = 8 - [ (gogoproto.nullable) = false ]; + // UnbondingOpsIndex defines the unbonding operations waiting on this consumer + // chain + repeated interchain_security.ccv.provider.v1.VscUnbondingOps + unbonding_ops_index = 8 [ (gogoproto.nullable) = false ]; } -// ValsetUpdateIdToHeight defines the genesis information for the mapping +// ValsetUpdateIdToHeight defines the genesis information for the mapping // of each valset udpate id to a block height message ValsetUpdateIdToHeight { - uint64 valset_update_id = 1; - uint64 height = 2; + uint64 valset_update_id = 1; + uint64 height = 2; } diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 0f3e4f3c9f..f235f0831a 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/provider/types"; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; @@ -11,131 +11,157 @@ import "ibc/core/client/v1/client.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/crypto/keys.proto"; import "cosmos/evidence/v1beta1/evidence.proto"; +import "cosmos/base/v1beta1/coin.proto"; -// ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain. -// If it passes, then all validators on the provider chain are expected to validate the consumer chain at spawn time -// or get slashed. It is recommended that spawn time occurs after the proposal end time. +// ConsumerAdditionProposal is a governance proposal on the provider chain to +// spawn a new consumer chain. If it passes, then all validators on the provider +// chain are expected to validate the consumer chain at spawn time or get +// slashed. It is recommended that spawn time occurs after the proposal end +// time. message ConsumerAdditionProposal { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // the title of the proposal - string title = 1; - // the description of the proposal - string description = 2; - // the proposed chain-id of the new consumer chain, must be different from all other consumer chain ids of the executing - // provider chain. - string chain_id = 3 ; - // the proposed initial height of new consumer chain. - // For a completely new chain, this will be {0,1}. However, it may be different if this is a chain that is converting to a consumer chain. - ibc.core.client.v1.Height initial_height = 4 [(gogoproto.nullable) = false]; - // The hash of the consumer chain genesis state without the consumer CCV module genesis params. - // It is used for off-chain confirmation of genesis.json validity by validators and other parties. - bytes genesis_hash = 5 ; - // The hash of the consumer chain binary that should be run by validators on chain initialization. - // It is used for off-chain confirmation of binary validity by validators and other parties. - bytes binary_hash = 6 ; - // spawn time is the time on the provider chain at which the consumer chain genesis is finalized and all validators - // will be responsible for starting their consumer chain validator node. - google.protobuf.Timestamp spawn_time = 7 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - - // Unbonding period for the consumer, - // which should be smaller than that of the provider in general. - google.protobuf.Duration unbonding_period = 8 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // Sent CCV related IBC packets will timeout after this duration - google.protobuf.Duration ccv_timeout_period = 9 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // Sent transfer related IBC packets will timeout after this duration - google.protobuf.Duration transfer_timeout_period = 10 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // The fraction of tokens allocated to the consumer redistribution address - // during distribution events. The fraction is a string representing a - // decimal number. For example "0.75" would represent 75%. - string consumer_redistribution_fraction = 11; - // BlocksPerDistributionTransmission is the number of blocks between ibc-token-transfers from the consumer chain to the provider chain. - // On sending transmission event, `consumer_redistribution_fraction` of the accumulated tokens are sent to the consumer redistribution address. - int64 blocks_per_distribution_transmission = 12; - // The number of historical info entries to persist in store. - // This param is a part of the cosmos sdk staking module. In the case of - // a ccv enabled consumer chain, the ccv module acts as the staking module. - int64 historical_entries = 13; -} - -// ConsumerRemovalProposal is a governance proposal on the provider chain to remove (and stop) a consumer chain. -// If it passes, all the consumer chain's state is removed from the provider chain. The outstanding unbonding -// operation funds are released. + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // the title of the proposal + string title = 1; + // the description of the proposal + string description = 2; + // the proposed chain-id of the new consumer chain, must be different from all + // other consumer chain ids of the executing provider chain. + string chain_id = 3; + // the proposed initial height of new consumer chain. + // For a completely new chain, this will be {0,1}. However, it may be + // different if this is a chain that is converting to a consumer chain. + ibc.core.client.v1.Height initial_height = 4 [ (gogoproto.nullable) = false ]; + // The hash of the consumer chain genesis state without the consumer CCV + // module genesis params. It is used for off-chain confirmation of + // genesis.json validity by validators and other parties. + bytes genesis_hash = 5; + // The hash of the consumer chain binary that should be run by validators on + // chain initialization. It is used for off-chain confirmation of binary + // validity by validators and other parties. + bytes binary_hash = 6; + // spawn time is the time on the provider chain at which the consumer chain + // genesis is finalized and all validators will be responsible for starting + // their consumer chain validator node. + google.protobuf.Timestamp spawn_time = 7 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + + // Unbonding period for the consumer, + // which should be smaller than that of the provider in general. + google.protobuf.Duration unbonding_period = 8 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Sent CCV related IBC packets will timeout after this duration + google.protobuf.Duration ccv_timeout_period = 9 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Sent transfer related IBC packets will timeout after this duration + google.protobuf.Duration transfer_timeout_period = 10 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // The fraction of tokens allocated to the consumer redistribution address + // during distribution events. The fraction is a string representing a + // decimal number. For example "0.75" would represent 75%. + string consumer_redistribution_fraction = 11; + // BlocksPerDistributionTransmission is the number of blocks between + // ibc-token-transfers from the consumer chain to the provider chain. On + // sending transmission event, `consumer_redistribution_fraction` of the + // accumulated tokens are sent to the consumer redistribution address. + int64 blocks_per_distribution_transmission = 12; + // The number of historical info entries to persist in store. + // This param is a part of the cosmos sdk staking module. In the case of + // a ccv enabled consumer chain, the ccv module acts as the staking module. + int64 historical_entries = 13; + // The ID of a token transfer channel used for the Reward Distribution + // sub-protocol. If DistributionTransmissionChannel == "", a new transfer + // channel is created on top of the same connection as the CCV channel. + // Note that transfer_channel_id is the ID of the channel end on the consumer + // chain. it is most relevant for chains performing a sovereign to consumer + // changeover in order to maintan the existing ibc transfer channel + string distribution_transmission_channel = 14; +} + +// ConsumerRemovalProposal is a governance proposal on the provider chain to +// remove (and stop) a consumer chain. If it passes, all the consumer chain's +// state is removed from the provider chain. The outstanding unbonding operation +// funds are released. message ConsumerRemovalProposal { - // the title of the proposal - string title = 1; - // the description of the proposal - string description = 2; - // the chain-id of the consumer chain to be stopped - string chain_id = 3; - // the time on the provider chain at which all validators are responsible to stop their consumer chain validator node - google.protobuf.Timestamp stop_time = 4 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - } + // the title of the proposal + string title = 1; + // the description of the proposal + string description = 2; + // the chain-id of the consumer chain to be stopped + string chain_id = 3; + // the time on the provider chain at which all validators are responsible to + // stop their consumer chain validator node + google.protobuf.Timestamp stop_time = 4 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; +} message EquivocationProposal { // the title of the proposal string title = 1; // the description of the proposal string description = 2; - // the list of equivocations that will be processed + // the list of equivocations that will be processed repeated cosmos.evidence.v1beta1.Equivocation equivocations = 3; } -// A persisted queue entry indicating that a slash packet data instance needs to be handled. -// This type belongs in the "global" queue, to coordinate slash packet handling times between consumers. +// A persisted queue entry indicating that a slash packet data instance needs to +// be handled. This type belongs in the "global" queue, to coordinate slash +// packet handling times between consumers. message GlobalSlashEntry { // Block time that slash packet was received by provider chain. // This field is used for store key iteration ordering. google.protobuf.Timestamp recv_time = 1 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; // The consumer that sent a slash packet. - string consumer_chain_id = 2 - [(gogoproto.customname) = "ConsumerChainID"]; - // The IBC sequence number of the recv packet. + string consumer_chain_id = 2 [ (gogoproto.customname) = "ConsumerChainID" ]; + // The IBC sequence number of the recv packet. // This field is used in the store key to ensure uniqueness. - uint64 ibc_seq_num = 3; - // The provider's consensus address of the validator being slashed. + uint64 ibc_seq_num = 3; + // The provider's consensus address of the validator being slashed. // This field is used to obtain validator power in HandleThrottleQueues. - // - // This field is not used in the store key, but is persisted in value bytes, see QueueGlobalSlashEntry. - ProviderConsAddress provider_val_cons_addr = 4; + // + // This field is not used in the store key, but is persisted in value bytes, + // see QueueGlobalSlashEntry. + bytes provider_val_cons_addr = 4; } - + // Params defines the parameters for CCV Provider module message Params { ibc.lightclients.tendermint.v1.ClientState template_client = 1; - // TrustingPeriodFraction is used to compute the consumer and provider IBC client's TrustingPeriod from the chain defined UnbondingPeriod + // TrustingPeriodFraction is used to compute the consumer and provider IBC + // client's TrustingPeriod from the chain defined UnbondingPeriod string trusting_period_fraction = 2; // Sent IBC packets will timeout after this duration google.protobuf.Duration ccv_timeout_period = 3 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // The channel initialization (IBC channel opening handshake) will timeout after this duration + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // The channel initialization (IBC channel opening handshake) will timeout + // after this duration google.protobuf.Duration init_timeout_period = 4 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // The VSC packets sent by the provider will timeout after this duration. - // Note that unlike ccv_timeout_period which is an IBC param, - // the vsc_timeout_period is a provider-side param that enables the provider - // to timeout VSC packets even when a consumer chain is not live. + // Note that unlike ccv_timeout_period which is an IBC param, + // the vsc_timeout_period is a provider-side param that enables the provider + // to timeout VSC packets even when a consumer chain is not live. google.protobuf.Duration vsc_timeout_period = 5 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // The period for which the slash meter is replenished google.protobuf.Duration slash_meter_replenish_period = 6 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // The fraction of total voting power that is replenished to the slash meter every replenish period. - // This param also serves as a maximum fraction of total voting power that the slash meter can hold. + // The fraction of total voting power that is replenished to the slash meter + // every replenish period. This param also serves as a maximum fraction of + // total voting power that the slash meter can hold. string slash_meter_replenish_fraction = 7; - // The maximum amount of throttled slash or vsc matured packets + // The maximum amount of throttled slash or vsc matured packets // that can be queued for a single consumer before the provider chain halts. int64 max_throttled_packets = 8; + + // The fee required to be paid to add a reward denom + cosmos.base.v1beta1.Coin consumer_reward_denom_registration_fee = 9 + [ (gogoproto.nullable) = false ]; } message HandshakeMetadata { @@ -145,35 +171,38 @@ message HandshakeMetadata { // SlashAcks contains cons addresses of consumer chain validators // successfully slashed on the provider chain -message SlashAcks { - repeated string addresses = 1; -} +message SlashAcks { repeated string addresses = 1; } -// ConsumerAdditionProposals holds pending governance proposals on the provider chain to spawn a new chain. +// ConsumerAdditionProposals holds pending governance proposals on the provider +// chain to spawn a new chain. message ConsumerAdditionProposals { // proposals waiting for spawn_time to pass repeated ConsumerAdditionProposal pending = 1; } -// ConsumerRemovalProposals holds pending governance proposals on the provider chain to remove (and stop) a consumer chain. +// ConsumerRemovalProposals holds pending governance proposals on the provider +// chain to remove (and stop) a consumer chain. message ConsumerRemovalProposals { // proposals waiting for stop_time to pass repeated ConsumerRemovalProposal pending = 1; } +// AddressList contains a list of consensus addresses +message AddressList { repeated bytes addresses = 1; } + message ChannelToChain { string channel_id = 1; string chain_id = 2; } // VscUnbondingOps contains the IDs of unbonding operations that are waiting for -// at least one VSCMaturedPacket with vscID from a consumer chain +// at least one VSCMaturedPacket with vscID from a consumer chain message VscUnbondingOps { uint64 vsc_id = 1; repeated uint64 unbonding_op_ids = 2; } -// UnbondingOp contains the ids of consumer chains that need to unbond before +// UnbondingOp contains the ids of consumer chains that need to unbond before // the unbonding operation with the given ID can unbond message UnbondingOp { uint64 id = 1; @@ -188,54 +217,36 @@ message InitTimeoutTimestamp { message VscSendTimestamp { uint64 vsc_id = 1; - google.protobuf.Timestamp timestamp = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp timestamp = 2 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; } // // Key assignment section // -// A validator's assigned consensus address for a consumer chain. -// Note this type is for type safety within provider code, consumer code uses normal sdk.ConsAddress, -// since there's no notion of provider vs consumer address. -message ConsumerConsAddress { - // Do not generate stringer for this type, we'll use sdk.ConsAddress.String() instead - option (gogoproto.goproto_stringer) = false; - bytes address = 1; -} - -// A validator's consensus address on the provider chain -message ProviderConsAddress { - // Do not generate stringer for this type, we'll use sdk.ConsAddress.String() instead - option (gogoproto.goproto_stringer) = false; - bytes address = 1; -} - -// ConsumerAddressList contains a list of consumer consensus addresses -message ConsumerAddressList { - repeated ConsumerConsAddress addresses = 1; -} - message KeyAssignmentReplacement { - ProviderConsAddress provider_addr = 1; + bytes provider_addr = 1; tendermint.crypto.PublicKey prev_c_key = 2; int64 power = 3; } // Used to serialize the ValidatorConsumerPubKey index from key assignment -// ValidatorConsumerPubKey: (chainID, providerAddr consAddr) -> consumerKey tmprotocrypto.PublicKey +// ValidatorConsumerPubKey: (chainID, providerAddr consAddr) -> consumerKey +// tmprotocrypto.PublicKey message ValidatorConsumerPubKey { string chain_id = 1; - ProviderConsAddress provider_addr = 2; + bytes provider_addr = 2; tendermint.crypto.PublicKey consumer_key = 3; } // Used to serialize the ValidatorConsumerAddr index from key assignment -// ValidatorByConsumerAddr: (chainID, consumerAddr consAddr) -> providerAddr consAddr +// ValidatorByConsumerAddr: (chainID, consumerAddr consAddr) -> providerAddr +// consAddr message ValidatorByConsumerAddr { string chain_id = 1; - ConsumerConsAddress consumer_addr = 2; - ProviderConsAddress provider_addr = 3; + bytes consumer_addr = 2; + bytes provider_addr = 3; } // Used to serialize the ConsumerAddrsToPrune index from key assignment @@ -243,5 +254,5 @@ message ValidatorByConsumerAddr { message ConsumerAddrsToPrune { string chain_id = 1; uint64 vsc_id = 2; - ConsumerAddressList consumer_addrs = 3; + AddressList consumer_addrs = 3; } diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index b1ef9a620c..4709b287dd 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/provider/types"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; @@ -10,7 +10,6 @@ import "interchain_security/ccv/v1/ccv.proto"; import "interchain_security/ccv/consumer/v1/genesis.proto"; import "interchain_security/ccv/provider/v1/provider.proto"; - service Query { // ConsumerGenesis queries the genesis state needed to start a consumer chain // whose proposal has been accepted @@ -46,27 +45,41 @@ service Query { // assigned by a validator for a consumer chain. rpc QueryValidatorConsumerAddr(QueryValidatorConsumerAddrRequest) returns (QueryValidatorConsumerAddrResponse) { - option (google.api.http).get = "/interchain_security/ccv/provider/validator_consumer_addr"; + option (google.api.http).get = + "/interchain_security/ccv/provider/validator_consumer_addr"; } // QueryProviderAddr returns the provider chain validator // given a consumer chain validator address rpc QueryValidatorProviderAddr(QueryValidatorProviderAddrRequest) returns (QueryValidatorProviderAddrResponse) { - option (google.api.http).get = "/interchain_security/ccv/provider/validator_provider_addr"; + option (google.api.http).get = + "/interchain_security/ccv/provider/validator_provider_addr"; } - // QueryThrottleState returns the main on-chain state relevant to currently throttled slash packets + // QueryThrottleState returns the main on-chain state relevant to currently + // throttled slash packets rpc QueryThrottleState(QueryThrottleStateRequest) returns (QueryThrottleStateResponse) { - option (google.api.http).get = "/interchain_security/ccv/provider/throttle_state"; + option (google.api.http).get = + "/interchain_security/ccv/provider/throttle_state"; } - // QueryThrottledConsumerPacketData returns a list of pending packet data instances - // (slash packet and vsc matured) for a single consumer chain + // QueryThrottledConsumerPacketData returns a list of pending packet data + // instances (slash packet and vsc matured) for a single consumer chain rpc QueryThrottledConsumerPacketData(QueryThrottledConsumerPacketDataRequest) returns (QueryThrottledConsumerPacketDataResponse) { - option (google.api.http).get = "/interchain_security/ccv/provider/pending_consumer_packets"; + option (google.api.http).get = + "/interchain_security/ccv/provider/pending_consumer_packets"; + } + + // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward + // denoms that are registered + rpc QueryRegisteredConsumerRewardDenoms( + QueryRegisteredConsumerRewardDenomsRequest) + returns (QueryRegisteredConsumerRewardDenomsResponse) { + option (google.api.http).get = + "/interchain_security/ccv/provider/registered_consumer_reward_denoms"; } } @@ -83,13 +96,13 @@ message QueryConsumerChainsResponse { repeated Chain chains = 1; } message QueryConsumerChainStartProposalsRequest {} -message QueryConsumerChainStartProposalsResponse { +message QueryConsumerChainStartProposalsResponse { ConsumerAdditionProposals proposals = 1; } message QueryConsumerChainStopProposalsRequest {} -message QueryConsumerChainStopProposalsResponse { +message QueryConsumerChainStopProposalsResponse { ConsumerRemovalProposals proposals = 1; } @@ -104,8 +117,7 @@ message QueryValidatorConsumerAddrRequest { // The id of the consumer chain string chain_id = 1; // The consensus address of the validator on the provider chain - string provider_address = 2 - [ (gogoproto.moretags) = "yaml:\"address\"" ]; + string provider_address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; } message QueryValidatorConsumerAddrResponse { @@ -119,8 +131,7 @@ message QueryValidatorProviderAddrRequest { // The id of the provider chain string chain_id = 1; // The consensus address of the validator on the consumer chain - string consumer_address = 2 - [ (gogoproto.moretags) = "yaml:\"address\"" ]; + string consumer_address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; } message QueryValidatorProviderAddrResponse { @@ -133,39 +144,46 @@ message QueryThrottleStateRequest {} message QueryThrottleStateResponse { // current slash_meter state int64 slash_meter = 1; - // allowance of voting power units (int) that the slash meter is given per replenish period - // this also serves as the max value for the meter. + // allowance of voting power units (int) that the slash meter is given per + // replenish period this also serves as the max value for the meter. int64 slash_meter_allowance = 2; - // next time the slash meter could potentially be replenished, iff it's not full + // next time the slash meter could potentially be replenished, iff it's not + // full google.protobuf.Timestamp next_replenish_candidate = 3 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; // data relevant to currently throttled slash packets repeated ThrottledSlashPacket packets = 4; } -message QueryThrottledConsumerPacketDataRequest { - string chain_id = 1; -} +message QueryThrottledConsumerPacketDataRequest { string chain_id = 1; } message QueryThrottledConsumerPacketDataResponse { string chain_id = 1; uint64 size = 2; repeated ThrottledPacketDataWrapper packetDataInstances = 3 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } -// A query wrapper type for the global entry and data relevant to a throttled slash packet. +// A query wrapper type for the global entry and data relevant to a throttled +// slash packet. message ThrottledSlashPacket { interchain_security.ccv.provider.v1.GlobalSlashEntry global_entry = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; interchain_security.ccv.v1.SlashPacketData data = 2 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } -// ThrottledPacketDataWrapper contains either SlashPacketData or VSCMaturedPacketData +// ThrottledPacketDataWrapper contains either SlashPacketData or +// VSCMaturedPacketData message ThrottledPacketDataWrapper { oneof data { interchain_security.ccv.v1.SlashPacketData slash_packet = 1; interchain_security.ccv.v1.VSCMaturedPacketData vsc_matured_packet = 2; } } + +message QueryRegisteredConsumerRewardDenomsRequest {} + +message QueryRegisteredConsumerRewardDenomsResponse { + repeated string denoms = 1; +} diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index 1e1a3d3fe6..3093132727 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/provider/types"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; @@ -10,7 +10,10 @@ import "google/protobuf/any.proto"; // Msg defines the Msg service. service Msg { - rpc AssignConsumerKey(MsgAssignConsumerKey) returns (MsgAssignConsumerKeyResponse); + rpc AssignConsumerKey(MsgAssignConsumerKey) + returns (MsgAssignConsumerKeyResponse); + rpc RegisterConsumerRewardDenom(MsgRegisterConsumerRewardDenom) + returns (MsgRegisterConsumerRewardDenomResponse); } message MsgAssignConsumerKey { @@ -19,12 +22,26 @@ message MsgAssignConsumerKey { // The chain id of the consumer chain to assign a consensus public key to string chain_id = 1; // The validator address on the provider - string provider_addr = 2 - [ (gogoproto.moretags) = "yaml:\"address\"" ]; + string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; // The consensus public key to use on the consumer. - // in json string format corresponding to proto-any, ex: + // in json string format corresponding to proto-any, ex: // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}` string consumer_key = 3; } -message MsgAssignConsumerKeyResponse {} \ No newline at end of file +message MsgAssignConsumerKeyResponse {} + +// MsgRegisterConsumerRewardDenom allows an account to register +// a consumer reward denom, i.e., add it to the list of denoms +// accepted by the provider as rewards. +message MsgRegisterConsumerRewardDenom { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string denom = 1; + string depositor = 2; +} + +// MsgRegisterConsumerRewardDenomResponse defines the +// Msg/RegisterConsumerRewardDenom response type. +message MsgRegisterConsumerRewardDenomResponse {} \ No newline at end of file diff --git a/proto/interchain_security/ccv/v1/ccv.proto b/proto/interchain_security/ccv/v1/ccv.proto index 6bc3ad7643..730366ea7f 100644 --- a/proto/interchain_security/ccv/v1/ccv.proto +++ b/proto/interchain_security/ccv/v1/ccv.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.v1; -option go_package = "github.com/cosmos/interchain-security/x/ccv/types"; +option go_package = "github.com/cosmos/interchain-security/v2/x/ccv/types"; import "cosmos/staking/v1beta1/staking.proto"; @@ -27,9 +27,8 @@ message ValidatorSetChangePacketData { // List of ccv.ValidatorSetChangePacketData. message ValidatorSetChangePackets { - repeated ValidatorSetChangePacketData list = 1 [ - (gogoproto.nullable) = false - ]; + repeated ValidatorSetChangePacketData list = 1 + [ (gogoproto.nullable) = false ]; } // This packet is sent from the consumer chain to the provider chain @@ -53,14 +52,13 @@ message SlashPacketData { cosmos.staking.v1beta1.Infraction infraction = 3; } -// MaturedUnbondingOps defines a list of ids corresponding to ids of matured unbonding operations. -message MaturedUnbondingOps { - repeated uint64 ids = 1; -} +// MaturedUnbondingOps defines a list of ids corresponding to ids of matured +// unbonding operations. +message MaturedUnbondingOps { repeated uint64 ids = 1; } // ConsumerPacketData contains a consumer packet data and a type tag message ConsumerPacketData { - ConsumerPacketDataType type = 1; + ConsumerPacketDataType type = 1; oneof data { SlashPacketData slashPacketData = 2; @@ -68,22 +66,22 @@ message ConsumerPacketData { } } - // ConsumerPacketDataList is a list of consumer packet data packets. message ConsumerPacketDataList { - repeated ConsumerPacketData list = 1 - [ (gogoproto.nullable) = false ]; + repeated ConsumerPacketData list = 1 [ (gogoproto.nullable) = false ]; } - // ConsumerPacketType indicates interchain security specific packet types. enum ConsumerPacketDataType { option (gogoproto.goproto_enum_prefix) = false; // UNSPECIFIED packet type - CONSUMER_PACKET_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UnspecifiedPacket"]; + CONSUMER_PACKET_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; // Slash packet - CONSUMER_PACKET_TYPE_SLASH = 1 [(gogoproto.enumvalue_customname) = "SlashPacket"]; + CONSUMER_PACKET_TYPE_SLASH = 1 + [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; // VSCMatured packet - CONSUMER_PACKET_TYPE_VSCM = 2 [(gogoproto.enumvalue_customname) = "VscMaturedPacket"]; + CONSUMER_PACKET_TYPE_VSCM = 2 + [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ]; } \ No newline at end of file diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index a10f01d5fa..a6ca6098e4 100644 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -16,6 +16,6 @@ done cd .. # move proto files to the right places -cp -r github.com/cosmos/interchain-security/* ./ +cp -r github.com/cosmos/interchain-security/v2/* ./ rm -rf github.com diff --git a/tests/difference/core/driver/core_test.go b/tests/difference/core/driver/core_test.go index bf9afc09fc..df20aef074 100644 --- a/tests/difference/core/driver/core_test.go +++ b/tests/difference/core/driver/core_test.go @@ -9,18 +9,18 @@ import ( "github.com/stretchr/testify/suite" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - appConsumer "github.com/cosmos/interchain-security/app/consumer" - appProvider "github.com/cosmos/interchain-security/app/provider" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer" + appProvider "github.com/cosmos/interchain-security/v2/app/provider" - simibc "github.com/cosmos/interchain-security/testutil/simibc" + simibc "github.com/cosmos/interchain-security/v2/testutil/simibc" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" ) type CoreSuite struct { diff --git a/tests/difference/core/driver/setup.go b/tests/difference/core/driver/setup.go index dec5e3203e..1e77588c64 100644 --- a/tests/difference/core/driver/setup.go +++ b/tests/difference/core/driver/setup.go @@ -19,7 +19,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -33,15 +33,15 @@ import ( slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - appConsumer "github.com/cosmos/interchain-security/app/consumer" - appProvider "github.com/cosmos/interchain-security/app/provider" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" - simibc "github.com/cosmos/interchain-security/testutil/simibc" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - - ccv "github.com/cosmos/interchain-security/x/ccv/types" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer" + appProvider "github.com/cosmos/interchain-security/v2/app/provider" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" + simibc "github.com/cosmos/interchain-security/v2/testutil/simibc" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) type Builder struct { @@ -537,6 +537,8 @@ func (b *Builder) createConsumerGenesis(client *ibctmtypes.ClientState) *consume consumertypes.DefaultHistoricalEntries, b.initState.UnbondingC, "0", // disable soft opt-out + []string{}, + []string{}, ) return consumertypes.NewInitialGenesisState(client, providerConsState, valUpdates, params) } diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 81ee07f7a9..a16f6b3bd4 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "log" + "math" "os/exec" "strconv" "strings" @@ -13,11 +14,11 @@ import ( evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - "github.com/tidwall/gjson" - "github.com/cosmos/interchain-security/x/ccv/provider/client" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/client" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + "github.com/tidwall/gjson" ) type SendTokensAction struct { @@ -74,7 +75,7 @@ type StartChainValidator struct { stake uint } -func (tr TestRun) startChain( +func (tr *TestRun) startChain( action StartChainAction, verbose bool, ) { @@ -124,6 +125,13 @@ func (tr TestRun) startChain( genesisChanges = chainConfig.genesisChanges } + var cometmockArg string + if tr.useCometmock { + cometmockArg = "true" + } else { + cometmockArg = "false" + } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "/bin/bash", "/testnet-scripts/start-chain.sh", chainConfig.binaryName, string(vals), @@ -134,6 +142,7 @@ func (tr TestRun) startChain( // lower timeout_commit means the blocks are produced faster making the test run shorter // with short timeout_commit (eg. timeout_commit = 1s) some nodes may miss blocks causing the test run to fail tr.tendermintConfigOverride, + cometmockArg, ) cmdReader, err := cmd.StdoutPipe() @@ -165,6 +174,14 @@ func (tr TestRun) startChain( chain: action.chain, validator: action.validators[0].id, }, verbose) + + // store the fact that we started the chain + tr.runningChains[action.chain] = true + fmt.Println("Started chain", action.chain) + if tr.timeOffset != 0 { + // advance time for this chain so that it is in sync with the rest of the network + tr.AdvanceTimeForChain(action.chain, tr.timeOffset) + } } type submitTextProposalAction struct { @@ -202,12 +219,14 @@ func (tr TestRun) submitTextProposal( } type submitConsumerAdditionProposalAction struct { - chain chainID - from validatorID - deposit uint - consumerChain chainID - spawnTime uint - initialHeight clienttypes.Height + preCCV bool + chain chainID + from validatorID + deposit uint + consumerChain chainID + spawnTime uint + initialHeight clienttypes.Height + distributionChannel string } func (tr TestRun) submitConsumerAdditionProposal( @@ -231,6 +250,7 @@ func (tr TestRun) submitConsumerAdditionProposal( TransferTimeoutPeriod: params.TransferTimeoutPeriod, UnbondingPeriod: params.UnbondingPeriod, Deposit: fmt.Sprint(action.deposit) + `stake`, + DistributionTransmissionChannel: action.distributionChannel, } bz, err := json.Marshal(prop) @@ -484,7 +504,7 @@ type voteGovProposalAction struct { propNumber uint } -func (tr TestRun) voteGovProposal( +func (tr *TestRun) voteGovProposal( action voteGovProposalAction, verbose bool, ) { @@ -527,7 +547,7 @@ type startConsumerChainAction struct { genesisChanges string } -func (tr TestRun) startConsumerChain( +func (tr *TestRun) startConsumerChain( action startConsumerChainAction, verbose bool, ) { @@ -564,6 +584,133 @@ func (tr TestRun) startConsumerChain( }, verbose) } +type ChangeoverChainAction struct { + sovereignChain chainID + providerChain chainID + validators []StartChainValidator + genesisChanges string +} + +func (tr TestRun) changeoverChain( + action ChangeoverChainAction, + verbose bool, +) { + // sleep until the consumer chain genesis is ready on consumer + time.Sleep(5 * time.Second) + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, tr.chainConfigs[action.providerChain].binaryName, + + "query", "provider", "consumer-genesis", + string(tr.chainConfigs[action.sovereignChain].chainId), + + `--node`, tr.getQueryNode(action.providerChain), + `-o`, `json`, + ) + + if verbose { + log.Println("changeoverChain cmd: ", cmd.String()) + } + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + consumerGenesis := ".app_state.ccvconsumer = " + string(bz) + consumerGenesisChanges := tr.chainConfigs[action.sovereignChain].genesisChanges + if consumerGenesisChanges != "" { + consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.genesisChanges + } + + tr.startChangeover(ChangeoverChainAction{ + validators: action.validators, + genesisChanges: consumerGenesis, + }, verbose) +} + +func (tr TestRun) startChangeover( + action ChangeoverChainAction, + verbose bool, +) { + chainConfig := tr.chainConfigs[chainID("sover")] + type jsonValAttrs struct { + Mnemonic string `json:"mnemonic"` + Allocation string `json:"allocation"` + Stake string `json:"stake"` + ValId string `json:"val_id"` + PrivValidatorKey string `json:"priv_validator_key"` + NodeKey string `json:"node_key"` + IpSuffix string `json:"ip_suffix"` + + ConsumerMnemonic string `json:"consumer_mnemonic"` + ConsumerPrivValidatorKey string `json:"consumer_priv_validator_key"` + StartWithConsumerKey bool `json:"start_with_consumer_key"` + } + + var validators []jsonValAttrs + for _, val := range action.validators { + validators = append(validators, jsonValAttrs{ + Mnemonic: tr.validatorConfigs[val.id].mnemonic, + NodeKey: tr.validatorConfigs[val.id].nodeKey, + ValId: fmt.Sprint(val.id), + PrivValidatorKey: tr.validatorConfigs[val.id].privValidatorKey, + Allocation: fmt.Sprint(val.allocation) + "stake", + Stake: fmt.Sprint(val.stake) + "stake", + IpSuffix: tr.validatorConfigs[val.id].ipSuffix, + + ConsumerMnemonic: tr.validatorConfigs[val.id].consumerMnemonic, + ConsumerPrivValidatorKey: tr.validatorConfigs[val.id].consumerPrivValidatorKey, + // if true node will be started with consumer key for each consumer chain + StartWithConsumerKey: tr.validatorConfigs[val.id].useConsumerKey, + }) + } + + vals, err := json.Marshal(validators) + if err != nil { + log.Fatal(err) + } + + // Concat genesis changes defined in chain config, with any custom genesis changes for this chain instantiation + var genesisChanges string + if action.genesisChanges != "" { + genesisChanges = chainConfig.genesisChanges + " | " + action.genesisChanges + } else { + genesisChanges = chainConfig.genesisChanges + } + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "/bin/bash", + "/testnet-scripts/start-changeover.sh", chainConfig.upgradeBinary, string(vals), + "sover", chainConfig.ipPrefix, genesisChanges, + tr.tendermintConfigOverride, + ) + + cmdReader, err := cmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + cmd.Stderr = cmd.Stdout + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + scanner := bufio.NewScanner(cmdReader) + + for scanner.Scan() { + out := scanner.Text() + if verbose { + fmt.Println("startChangeover: " + out) + } + if out == done { + break + } + } + if err := scanner.Err(); err != nil { + log.Fatal("startChangeover died", err) + } +} + type addChainToRelayerAction struct { chain chainID validator validatorID @@ -594,9 +741,80 @@ websocket_addr = "%s" numerator = "1" ` +// Set up the config for a new chain for gorelayer. +// This config is added to the container as a file. +// We then add the chain to the relayer, using this config as the chain config with `rly chains add --file` +// This is functionally similar to the config used by Hermes for chains, e.g. gas is free. +const gorelayerChainConfigTemplate = ` +{ + "type": "cosmos", + "value": { + "key": "default", + "chain-id": "%s", + "rpc-addr": "%s", + "account-prefix": "cosmos", + "keyring-backend": "test", + "gas-adjustment": 1.2, + "gas-prices": "0.00stake", + "debug": true, + "timeout": "20s", + "output-format": "json", + "sign-mode": "direct" + } +}` + func (tr TestRun) addChainToRelayer( action addChainToRelayerAction, verbose bool, +) { + if !tr.useGorelayer { + tr.addChainToHermes(action, verbose) + } else { + tr.addChainToGorelayer(action, verbose) + } +} + +func (tr TestRun) addChainToGorelayer( + action addChainToRelayerAction, + verbose bool, +) { + queryNodeIP := tr.getQueryNodeIP(action.chain) + chainId := tr.chainConfigs[action.chain].chainId + rpcAddr := "http://" + queryNodeIP + ":26658" + + chainConfig := fmt.Sprintf(gorelayerChainConfigTemplate, + chainId, + rpcAddr, + ) + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + bz, err := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", "config", "init").CombinedOutput() + if err != nil && !strings.Contains(string(bz), "config already exists") { + log.Fatal(err, "\n", string(bz)) + } + + chainConfigFileName := fmt.Sprintf("/root/%s_config.json", chainId) + + bashCommand := fmt.Sprintf(`echo '%s' >> %s`, chainConfig, chainConfigFileName) + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + bz, err = exec.Command("docker", "exec", tr.containerConfig.instanceName, "bash", "-c", + bashCommand).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + addChainCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", "chains", "add", "--file", chainConfigFileName, string(chainId)) + executeCommand(addChainCommand, "add chain") + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + keyRestoreCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", "keys", "restore", string(chainId), "default", tr.validatorConfigs[action.validator].mnemonic) + executeCommand(keyRestoreCommand, "restore keys") +} + +func (tr TestRun) addChainToHermes( + action addChainToRelayerAction, + verbose bool, ) { queryNodeIP := tr.getQueryNodeIP(action.chain) chainId := tr.chainConfigs[action.chain].chainId @@ -611,6 +829,7 @@ func (tr TestRun) addChainToRelayer( keyName, rpcAddr, wsAddr, + // action.consumer, ) bashCommand := fmt.Sprintf(`echo '%s' >> %s`, chainConfig, "/root/.hermes/config.toml") @@ -645,6 +864,26 @@ func (tr TestRun) addChainToRelayer( } } +// This config file is used by gorelayer to create a path between chains. +// Since the tests assume we use a certain client-id for certain paths, +// in the config we specify the client id, e.g. 07-tendermint-5. +// The src-channel-filter is empty because we want to relay all channels. +const gorelayerPathConfigTemplate = `{ + "src": { + "chain-id": "%s", + "client-id": "07-tendermint-%v" + }, + "dst": { + "chain-id": "%s", + "client-id": "07-tendermint-%v" + }, + "src-channel-filter": { + "rule": "", + "channel-list": [] + } +} +` + type addIbcConnectionAction struct { chainA chainID chainB chainID @@ -655,6 +894,112 @@ type addIbcConnectionAction struct { func (tr TestRun) addIbcConnection( action addIbcConnectionAction, verbose bool, +) { + if !tr.useGorelayer { + tr.addIbcConnectionHermes(action, verbose) + } else { + tr.addIbcConnectionGorelayer(action, verbose) + } +} + +func (tr TestRun) addIbcConnectionGorelayer( + action addIbcConnectionAction, + verbose bool, +) { + pathName := tr.GetPathNameForGorelayer(action.chainA, action.chainB) + + pathConfig := fmt.Sprintf(gorelayerPathConfigTemplate, action.chainA, action.clientA, action.chainB, action.clientB) + + pathConfigFileName := fmt.Sprintf("/root/%s_config.json", pathName) + + bashCommand := fmt.Sprintf(`echo '%s' >> %s`, pathConfig, pathConfigFileName) + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + pathConfigCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "bash", "-c", + bashCommand) + executeCommand(pathConfigCommand, "add path config") + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + newPathCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", + "paths", "add", + string(tr.chainConfigs[action.chainA].chainId), + string(tr.chainConfigs[action.chainB].chainId), + pathName, + "--file", pathConfigFileName, + ) + + executeCommand(newPathCommand, "new path") + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + newClientsCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", + "transact", "clients", + pathName, + ) + + executeCommand(newClientsCommand, "new clients") + + tr.waitBlocks(action.chainA, 1, 10*time.Second) + tr.waitBlocks(action.chainB, 1, 10*time.Second) + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + newConnectionCommand := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", + "transact", "connection", + pathName, + ) + + executeCommand(newConnectionCommand, "new connection") + + tr.waitBlocks(action.chainA, 1, 10*time.Second) + tr.waitBlocks(action.chainB, 1, 10*time.Second) +} + +type createIbcClientsAction struct { + chainA chainID + chainB chainID +} + +// if clients are not provided hermes will first +// create new clients and then a new connection +// otherwise, it would use client provided as CLI argument (-a-client) +func (tr TestRun) createIbcClientsHermes( + action createIbcClientsAction, + verbose bool, +) { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "hermes", + "create", "connection", + "--a-chain", string(tr.chainConfigs[action.chainA].chainId), + "--b-chain", string(tr.chainConfigs[action.chainB].chainId), + ) + + cmdReader, err := cmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + cmd.Stderr = cmd.Stdout + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + scanner := bufio.NewScanner(cmdReader) + + for scanner.Scan() { + out := scanner.Text() + if verbose { + fmt.Println("createIbcClientsHermes: " + out) + } + if out == done { + break + } + } + if err := scanner.Err(); err != nil { + log.Fatal(err) + } +} + +func (tr TestRun) addIbcConnectionHermes( + action addIbcConnectionAction, + verbose bool, ) { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "hermes", @@ -697,12 +1042,43 @@ type addIbcChannelAction struct { portA string portB string order string + version string +} + +type startRelayerAction struct{} + +func (tr TestRun) startRelayer( + action startRelayerAction, + verbose bool, +) { + if tr.useGorelayer { + tr.startGorelayer(action, verbose) + } else { + tr.startHermes(action, verbose) + } } -type startHermesAction struct{} +func (tr TestRun) startGorelayer( + action startRelayerAction, + verbose bool, +) { + // gorelayer start is running in detached mode + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", "-d", tr.containerConfig.instanceName, "rly", + "start", + ) + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + if verbose { + fmt.Println("started gorelayer") + } +} func (tr TestRun) startHermes( - action startHermesAction, + action startRelayerAction, verbose bool, ) { // hermes start is running in detached mode @@ -724,6 +1100,42 @@ func (tr TestRun) addIbcChannel( action addIbcChannelAction, verbose bool, ) { + if tr.useGorelayer { + tr.addIbcChannelGorelayer(action, verbose) + } else { + tr.addIbcChannelHermes(action, verbose) + } +} + +func (tr TestRun) addIbcChannelGorelayer( + action addIbcChannelAction, + verbose bool, +) { + pathName := tr.GetPathNameForGorelayer(action.chainA, action.chainB) + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", + "transact", "channel", + pathName, + "--src-port", action.portA, + "--dst-port", action.portB, + "--version", tr.containerConfig.ccvVersion, + "--order", action.order, + "--debug", + ) + executeCommand(cmd, "addChannel") +} + +func (tr TestRun) addIbcChannelHermes( + action addIbcChannelAction, + verbose bool, +) { + // if version is not specified, use the default version when creating ccv connections + // otherwise, use the provided version schema (usually it is ICS20-1 for IBC transfer) + chanVersion := action.version + if chanVersion == "" { + chanVersion = tr.containerConfig.ccvVersion + } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "hermes", "create", "channel", @@ -731,7 +1143,7 @@ func (tr TestRun) addIbcChannel( "--a-connection", "connection-"+fmt.Sprint(action.connectionA), "--a-port", action.portA, "--b-port", action.portB, - "--channel-version", tr.containerConfig.ccvVersion, + "--channel-version", chanVersion, "--order", action.order, ) @@ -780,6 +1192,10 @@ func (tr TestRun) transferChannelComplete( action transferChannelCompleteAction, verbose bool, ) { + if tr.useGorelayer { + log.Fatal("transferChannelComplete is not implemented for rly") + } + //#nosec G204 -- Bypass linter warning for spawning subprocess with chanOpenTryCmd arguments. chanOpenTryCmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "hermes", "tx", "chan-open-try", @@ -820,8 +1236,8 @@ func (tr TestRun) transferChannelComplete( executeCommand(chanOpenConfirmCmd, "transferChanOpenConfirm") } -func executeCommand(cmd *exec.Cmd, cmdName string) { - if verbose != nil && *verbose { +func executeCommandWithVerbosity(cmd *exec.Cmd, cmdName string, verbose bool) { + if verbose { fmt.Println(cmdName+" cmd:", cmd.String()) } @@ -839,7 +1255,7 @@ func executeCommand(cmd *exec.Cmd, cmdName string) { for scanner.Scan() { out := scanner.Text() - if verbose != nil && *verbose { + if verbose { fmt.Println(cmdName + ": " + out) } } @@ -848,8 +1264,14 @@ func executeCommand(cmd *exec.Cmd, cmdName string) { } } +// Executes a command with verbosity specified by CLI flag +func executeCommand(cmd *exec.Cmd, cmdName string) { + executeCommandWithVerbosity(cmd, cmdName, *verbose) +} + type relayPacketsAction struct { - chain chainID + chainA chainID + chainB chainID port string channel uint } @@ -857,23 +1279,58 @@ type relayPacketsAction struct { func (tr TestRun) relayPackets( action relayPacketsAction, verbose bool, +) { + if tr.useGorelayer { + tr.relayPacketsGorelayer(action, verbose) + } else { + tr.relayPacketsHermes(action, verbose) + } +} + +func (tr TestRun) relayPacketsGorelayer( + action relayPacketsAction, + verbose bool, +) { + pathName := tr.GetPathNameForGorelayer(action.chainA, action.chainB) + + // rly transact relay-packets [path-name] --channel [channel-id] + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "rly", "transact", "flush", + pathName, + "channel-"+fmt.Sprint(action.channel), + ) + if verbose { + log.Println("relayPackets cmd:", cmd.String()) + } + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + tr.waitBlocks(action.chainA, 1, 30*time.Second) +} + +func (tr TestRun) relayPacketsHermes( + action relayPacketsAction, + verbose bool, ) { // hermes clear packets ibc0 transfer channel-13 //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "hermes", "clear", "packets", - "--chain", string(tr.chainConfigs[action.chain].chainId), + "--chain", string(tr.chainConfigs[action.chainA].chainId), "--port", action.port, "--channel", "channel-"+fmt.Sprint(action.channel), ) if verbose { log.Println("relayPackets cmd:", cmd.String()) } + bz, err := cmd.CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - tr.waitBlocks(action.chain, 2, 60*time.Second) + tr.waitBlocks(action.chainA, 1, 30*time.Second) } type relayRewardPacketsToProviderAction struct { @@ -893,7 +1350,7 @@ func (tr TestRun) relayRewardPacketsToProvider( tr.waitBlocks(action.consumerChain, uint(blockPerDistribution-currentBlock+1), 60*time.Second) } - tr.relayPackets(relayPacketsAction{chain: action.consumerChain, port: action.port, channel: action.channel}, verbose) + tr.relayPackets(relayPacketsAction{chainA: action.consumerChain, chainB: action.providerChain, port: action.port, channel: action.channel}, verbose) tr.waitBlocks(action.providerChain, 1, 10*time.Second) } @@ -1112,6 +1569,20 @@ type downtimeSlashAction struct { validator validatorID } +// takes a string representation of the private key like +// `{"address":"DF090A4880B54CD57B2A79E64D9E969BD7514B09","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"TRJgf7lkTjs/sj43pyweEOanyV7H7fhnVivOi0A4yjW6NjXgCCilX3TshiA8CT/nHxz3brtLh9B/z2fJ4I9N6w=="}}` +// and returns the value of the "address" field +func (tr TestRun) getValidatorKeyAddressFromString(keystring string) string { + var key struct { + Address string `json:"address"` + } + err := json.Unmarshal([]byte(keystring), &key) + if err != nil { + log.Fatal(err) + } + return key.Address +} + func (tr TestRun) invokeDowntimeSlash(action downtimeSlashAction, verbose bool) { // Bring validator down tr.setValidatorDowntime(action.chain, action.validator, true, verbose) @@ -1130,6 +1601,30 @@ func (tr TestRun) setValidatorDowntime(chain chainID, validator validatorID, dow lastArg = "up" } + if tr.useCometmock { + // send set_signing_status either to down or up for validator + var validatorAddress string + if chain == chainID("provi") { + validatorAddress = tr.getValidatorKeyAddressFromString(tr.validatorConfigs[validator].privValidatorKey) + } else { + var valAddressString string + if tr.validatorConfigs[validator].useConsumerKey { + valAddressString = tr.validatorConfigs[validator].consumerPrivValidatorKey + } else { + valAddressString = tr.validatorConfigs[validator].privValidatorKey + } + validatorAddress = tr.getValidatorKeyAddressFromString(valAddressString) + } + + method := "set_signing_status" + params := fmt.Sprintf(`{"private_key_address":"%s","status":"%s"}`, validatorAddress, lastArg) + address := tr.getQueryNodeRPCAddress(chain) + + tr.curlJsonRPCRequest(method, params, address) + tr.waitBlocks(chain, 1, 10*time.Second) + return + } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command( "docker", @@ -1248,6 +1743,36 @@ func (tr TestRun) registerRepresentative( wg.Wait() } +type registerConsumerRewardDenomAction struct { + chain chainID + from validatorID + denom string +} + +func (tr TestRun) registerConsumerRewardDenom(action registerConsumerRewardDenomAction, verbose bool) { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + bz, err := exec.Command("docker", "exec", tr.containerConfig.instanceName, tr.chainConfigs[action.chain].binaryName, + "tx", "provider", "register-consumer-reward-denom", action.denom, + + `--from`, `validator`+fmt.Sprint(action.from), + `--chain-id`, string(action.chain), + `--home`, tr.getValidatorHome(action.chain, action.from), + `--node`, tr.getValidatorNode(action.chain, action.from), + `--gas`, "9000000", + `--keyring-backend`, `test`, + `-b`, `block`, + `-y`, + ).CombinedOutput() + + if verbose { + fmt.Println("redelegate cmd:", string(bz)) + } + + if err != nil { + log.Fatal(err, "\n", string(bz)) + } +} + // Creates an additional node on selected chain // by copying an existing validator's home folder // @@ -1368,6 +1893,8 @@ func (tr TestRun) assignConsumerPubKey(action assignConsumerPubKeyAction, verbos // TODO: @MSalopek refactor this so test config is not changed at runtime // make the validator use consumer key + // @POfftermatt I am currently using this for downtime slashing with cometmock + // (I need to find the currently used validator key address)Í valCfg.useConsumerKey = true tr.validatorConfigs[action.validator] = valCfg } @@ -1421,3 +1948,48 @@ func (tr TestRun) waitForSlashThrottleDequeue( func uintPointer(i uint) *uint { return &i } + +// GetPathNameForGorelayer returns the name of the path between two given chains used by Gorelayer. +// Since paths are bidirectional, we need either chain to be able to be provided as first or second argument +// and still return the same name, so we sort the chain names alphabetically. +func (tr TestRun) GetPathNameForGorelayer(chainA, chainB chainID) string { + var pathName string + if string(chainA) < string(chainB) { + pathName = string(chainA) + "-" + string(chainB) + } else { + pathName = string(chainB) + "-" + string(chainA) + } + + return pathName +} + +// WaitTime waits for the given duration. +// The CometMock version of this takes a pointer to the TestRun as it needs to manipulate +// information in the testrun that stores how much each chain has waited, to keep times in sync. +// Be careful that all functions calling WaitTime should therefore also take a pointer to the TestRun. +func (tr *TestRun) WaitTime(duration time.Duration) { + if !tr.useCometmock { + time.Sleep(duration) + } else { + tr.timeOffset += duration + for chain, running := range tr.runningChains { + if !running { + continue + } + tr.AdvanceTimeForChain(chain, duration) + } + } +} + +func (tr TestRun) AdvanceTimeForChain(chain chainID, duration time.Duration) { + // cometmock avoids sleeping, and instead advances time for all chains + method := "advance_time" + params := fmt.Sprintf(`{"duration_in_seconds": "%d"}`, int(math.Ceil(duration.Seconds()))) + + address := tr.getQueryNodeRPCAddress(chain) + + tr.curlJsonRPCRequest(method, params, address) + + // wait for 1 block of the chain to get a block with the advanced timestamp + tr.waitBlocks(chain, 1, time.Minute) +} diff --git a/tests/e2e/actions_sovereign_chain.go b/tests/e2e/actions_sovereign_chain.go new file mode 100644 index 0000000000..c61a2a9a38 --- /dev/null +++ b/tests/e2e/actions_sovereign_chain.go @@ -0,0 +1,166 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "log" + "os/exec" + "time" +) + +type StartSovereignChainAction struct { + chain chainID + validators []StartChainValidator + // Genesis changes specific to this action, appended to genesis changes defined in chain config + genesisChanges string +} + +// calls a simplified startup script (start-sovereign.sh) and runs a validator node +// upgrades are simpler with a single validator node since only one node needs to be upgraded +func (tr TestRun) startSovereignChain( + action StartSovereignChainAction, + verbose bool, +) { + chainConfig := tr.chainConfigs["sover"] + type jsonValAttrs struct { + Mnemonic string `json:"mnemonic"` + Allocation string `json:"allocation"` + Stake string `json:"stake"` + ValId string `json:"val_id"` + PrivValidatorKey string `json:"priv_validator_key"` + NodeKey string `json:"node_key"` + IpSuffix string `json:"ip_suffix"` + + ConsumerMnemonic string `json:"consumer_mnemonic"` + ConsumerPrivValidatorKey string `json:"consumer_priv_validator_key"` + StartWithConsumerKey bool `json:"start_with_consumer_key"` + } + + var validators []jsonValAttrs + for _, val := range action.validators { + validators = append(validators, jsonValAttrs{ + Mnemonic: tr.validatorConfigs[val.id].mnemonic, + NodeKey: tr.validatorConfigs[val.id].nodeKey, + ValId: fmt.Sprint(val.id), + PrivValidatorKey: tr.validatorConfigs[val.id].privValidatorKey, + Allocation: fmt.Sprint(val.allocation) + "stake", + Stake: fmt.Sprint(val.stake) + "stake", + IpSuffix: tr.validatorConfigs[val.id].ipSuffix, + + ConsumerMnemonic: tr.validatorConfigs[val.id].consumerMnemonic, + ConsumerPrivValidatorKey: tr.validatorConfigs[val.id].consumerPrivValidatorKey, + // if true node will be started with consumer key for each consumer chain + StartWithConsumerKey: tr.validatorConfigs[val.id].useConsumerKey, + }) + } + + vals, err := json.Marshal(validators) + if err != nil { + log.Fatal(err) + } + + // Concat genesis changes defined in chain config, with any custom genesis changes for this chain instantiation + var genesisChanges string + if action.genesisChanges != "" { + genesisChanges = chainConfig.genesisChanges + " | " + action.genesisChanges + } else { + genesisChanges = chainConfig.genesisChanges + } + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "/bin/bash", + "/testnet-scripts/start-sovereign.sh", chainConfig.binaryName, string(vals), + string(chainConfig.chainId), chainConfig.ipPrefix, genesisChanges, + tr.tendermintConfigOverride, + ) + + cmdReader, err := cmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + cmd.Stderr = cmd.Stdout + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + scanner := bufio.NewScanner(cmdReader) + + for scanner.Scan() { + out := scanner.Text() + if verbose { + fmt.Println("startSovereignChain: " + out) + } + if out == done { + break + } + } + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + tr.addChainToRelayer(addChainToRelayerAction{ + chain: action.chain, + validator: action.validators[0].id, + }, verbose) +} + +type UpgradeProposalAction struct { + chainID chainID + upgradeTitle string + proposer validatorID + upgradeHeight uint64 +} + +func (tr *TestRun) submitUpgradeProposal(action UpgradeProposalAction, verbose bool) { + submit := fmt.Sprintf( + `%s tx gov submit-proposal software-upgrade %s \ + --title %s \ + --deposit 10000000stake \ + --upgrade-height %s \ + --upgrade-info "perform changeover" \ + --description "perform changeover" \ + --gas 900000 \ + --from validator%s \ + --keyring-backend test \ + --chain-id %s \ + --home %s \ + --node %s \ + -b block \ + -y`, + tr.chainConfigs[chainID("sover")].binaryName, + action.upgradeTitle, + action.upgradeTitle, + fmt.Sprint(action.upgradeHeight), + action.proposer, + tr.chainConfigs[chainID("sover")].chainId, + tr.getValidatorHome(chainID("sover"), action.proposer), + tr.getValidatorNode(chainID("sover"), action.proposer), + ) + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", + tr.containerConfig.instanceName, + "/bin/bash", "-c", + submit, + ) + + if verbose { + fmt.Println("submitUpgradeProposal cmd:", cmd.String()) + } + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } +} + +type waitUntilBlockAction struct { + block uint + chain chainID +} + +func (tr *TestRun) waitUntilBlockOnChain(action waitUntilBlockAction) { + fmt.Println("waitUntilBlockOnChain is waiting for block:", action.block) + tr.waitUntilBlock(action.chain, action.block, 120*time.Second) + fmt.Println("waitUntilBlockOnChain done waiting for block:", action.block) +} diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 578c9ea647..df54cbd4f4 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -47,6 +47,9 @@ type ChainConfig struct { // Example: ".app_state.gov.params.voting_period = \"5s\" | .app_state.slashing.params.signed_blocks_window = \"2\" | .app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\"" genesisChanges string binaryName string + + // binary to use after upgrade height + upgradeBinary string } type ContainerConfig struct { @@ -70,11 +73,22 @@ type TestRun struct { tendermintConfigOverride string localSdkPath string useGaia bool + useCometmock bool // if false, nodes run CometBFT + useGorelayer bool // if false, Hermes is used as the relayer gaiaTag string + // chains which are running, i.e. producing blocks, at the moment + runningChains map[chainID]bool + // Used with CometMock. The time by which chains have been advanced. Used to keep chains in sync: when a new chain is started, advance its time by this value to keep chains in sync. + timeOffset time.Duration name string } +// Initialize initializes the TestRun instance by setting the runningChains field to an empty map. +func (tr *TestRun) Initialize() { + tr.runningChains = make(map[chainID]bool) +} + func getDefaultValidators() map[validatorID]ValidatorConfig { return map[validatorID]ValidatorConfig{ validatorID("alice"): { @@ -138,7 +152,7 @@ func getDefaultValidators() map[validatorID]ValidatorConfig { } func SlashThrottleTestRun() TestRun { - return TestRun{ + tr := TestRun{ name: "slash-throttling", containerConfig: ContainerConfig{ containerName: "interchain-security-slash-container", @@ -178,10 +192,12 @@ func SlashThrottleTestRun() TestRun { tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "50ms"/;`, } + tr.Initialize() + return tr } func DefaultTestRun() TestRun { - return TestRun{ + tr := TestRun{ name: "default", containerConfig: ContainerConfig{ containerName: "interchain-security-container", @@ -221,10 +237,24 @@ func DefaultTestRun() TestRun { tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "50ms"/;`, } + tr.Initialize() + return tr } -func DemocracyTestRun() TestRun { - return TestRun{ +func DemocracyTestRun(allowReward bool) TestRun { + consumerGenChanges := ".app_state.ccvconsumer.params.blocks_per_distribution_transmission = \"20\" | " + + ".app_state.gov.voting_params.voting_period = \"10s\" | " + + ".app_state.slashing.params.signed_blocks_window = \"10\" | " + + ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + + ".app_state.slashing.params.downtime_jail_duration = \"60s\" | " + + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\"" + + if allowReward { + // This allows the consumer chain to send rewards in the stake denom + consumerGenChanges += " | .app_state.ccvconsumer.params.reward_denoms = [\"stake\"]" + } + + tr := TestRun{ name: "democracy", containerConfig: ContainerConfig{ containerName: "interchain-security-democ-container", @@ -253,21 +283,18 @@ func DemocracyTestRun() TestRun { binaryName: "interchain-security-cdd", ipPrefix: "7.7.9", votingWaitTime: 20, - genesisChanges: ".app_state.ccvconsumer.params.blocks_per_distribution_transmission = \"20\" | " + - ".app_state.gov.params.voting_period = \"10s\" | " + - ".app_state.slashing.params.signed_blocks_window = \"10\" | " + - ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + - ".app_state.slashing.params.downtime_jail_duration = \"60s\" | " + - ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\"", + genesisChanges: consumerGenChanges, }, }, tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "50ms"/;`, } + tr.Initialize() + return tr } func MultiConsumerTestRun() TestRun { - return TestRun{ + tr := TestRun{ name: "multi-consumer", containerConfig: ContainerConfig{ containerName: "interchain-security-multic-container", @@ -317,6 +344,55 @@ func MultiConsumerTestRun() TestRun { tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "3s"/;` + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "100ms"/;`, } + tr.Initialize() + return tr +} + +func ChangeoverTestRun() TestRun { + tr := TestRun{ + name: "changeover", + containerConfig: ContainerConfig{ + containerName: "interchain-security-changeover-container", + instanceName: "interchain-security-changeover-instance", + ccvVersion: "1", + now: time.Now(), + }, + validatorConfigs: getDefaultValidators(), + chainConfigs: map[chainID]ChainConfig{ + chainID("provi"): { + chainId: chainID("provi"), + binaryName: "interchain-security-pd", + ipPrefix: "7.7.7", + votingWaitTime: 20, + genesisChanges: ".app_state.gov.voting_params.voting_period = \"20s\" | " + + // Custom slashing parameters for testing validator downtime functionality + // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking + ".app_state.slashing.params.signed_blocks_window = \"10\" | " + + ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + + ".app_state.slashing.params.downtime_jail_duration = \"2s\" | " + + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\" | " + + ".app_state.provider.params.slash_meter_replenish_fraction = \"1.0\" | " + // This disables slash packet throttling + ".app_state.provider.params.slash_meter_replenish_period = \"3s\"", + }, + chainID("sover"): { + chainId: chainID("sover"), + binaryName: "interchain-security-sd", + upgradeBinary: "interchain-security-cdd", + ipPrefix: "7.7.8", + votingWaitTime: 20, + genesisChanges: ".app_state.gov.voting_params.voting_period = \"20s\" | " + + ".app_state.slashing.params.signed_blocks_window = \"15\" | " + + ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + + ".app_state.slashing.params.downtime_jail_duration = \"2s\" | " + + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\" | " + + ".app_state.staking.params.unbonding_time = \"1728000s\"", // making the genesis unbonding time equal to unbonding time in the consumer addition proposal + }, + }, + tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "50ms"/;`, + } + tr.Initialize() + return tr } func (s *TestRun) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) { @@ -332,6 +408,14 @@ func (s *TestRun) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag str s.localSdkPath = localSdkPath } +func (s *TestRun) SetCometMockConfig(useCometmock bool) { + s.useCometmock = useCometmock +} + +func (s *TestRun) SetRelayerConfig(useRly bool) { + s.useGorelayer = useRly +} + // validateStringLiterals enforces that configs follow the constraints // necessary to to execute the tests // diff --git a/tests/e2e/main.go b/tests/e2e/main.go index b147293943..00967dfcac 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -16,12 +16,19 @@ import ( ) var ( - verbose = flag.Bool("verbose", false, "turn verbose logging on/off") - happyPathOnly = flag.Bool("happy-path-only", false, "run happy path tests only") + verbose = flag.Bool("verbose", false, "turn verbose logging on/off") + happyPathOnly = flag.Bool("happy-path-only", false, "run happy path tests only") + shortHappyPathOnly = flag.Bool("short-happy-path", false, `run abridged happy path tests only. +This is like the happy path, but skips steps +that involve starting or stopping nodes for the same chain outside of the chain setup or teardown. +In particular, this skips steps related to downtime and double signing. +This is suited for CometMock+Gorelayer testing`) includeMultiConsumer = flag.Bool("include-multi-consumer", false, "include multiconsumer tests in run") parallel = flag.Bool("parallel", false, "run all tests in parallel") localSdkPath = flag.String("local-sdk-path", "", "path of a local sdk version to build and reference in integration tests") + useCometmock = flag.Bool("use-cometmock", false, "use cometmock instead of CometBFT") + useGorelayer = flag.Bool("use-gorelayer", false, "use go relayer instead of Hermes") ) var ( @@ -35,6 +42,13 @@ var ( func main() { flag.Parse() + if shortHappyPathOnly != nil && *shortHappyPathOnly { + fmt.Println("=============== running short happy path only ===============") + tr := DefaultTestRun() + tr.Run(shortHappyPathSteps, *localSdkPath, *useGaia, *gaiaTag) + return + } + if happyPathOnly != nil && *happyPathOnly { fmt.Println("=============== running happy path only ===============") tr := DefaultTestRun() @@ -43,8 +57,10 @@ func main() { } testRuns := []testRunWithSteps{ + {ChangeoverTestRun(), changeoverSteps}, {DefaultTestRun(), happyPathSteps}, - {DemocracyTestRun(), democracySteps}, + {DemocracyTestRun(true), democracySteps}, + {DemocracyTestRun(false), rewardDenomConsumerSteps}, {SlashThrottleTestRun(), slashThrottleSteps}, } if includeMultiConsumer != nil && *includeMultiConsumer { @@ -79,6 +95,8 @@ func main() { // Docker containers are torn down after the test run is complete. func (tr *TestRun) Run(steps []Step, localSdkPath string, useGaia bool, gaiaTag string) { tr.SetDockerConfig(localSdkPath, useGaia, gaiaTag) + tr.SetCometMockConfig(*useCometmock) + tr.SetRelayerConfig(*useGorelayer) tr.validateStringLiterals() tr.startDocker() @@ -95,6 +113,14 @@ func (tr *TestRun) runStep(step Step, verbose bool) { switch action := step.action.(type) { case StartChainAction: tr.startChain(action, verbose) + case StartSovereignChainAction: + tr.startSovereignChain(action, verbose) + case UpgradeProposalAction: + tr.submitUpgradeProposal(action, verbose) + case waitUntilBlockAction: + tr.waitUntilBlockOnChain(action) + case ChangeoverChainAction: + tr.changeoverChain(action, verbose) case SendTokensAction: tr.sendTokens(action, verbose) case submitTextProposalAction: @@ -113,6 +139,8 @@ func (tr *TestRun) runStep(step Step, verbose bool) { tr.startConsumerChain(action, verbose) case addChainToRelayerAction: tr.addChainToRelayer(action, verbose) + case createIbcClientsAction: + tr.createIbcClientsHermes(action, verbose) case addIbcConnectionAction: tr.addIbcConnection(action, verbose) case addIbcChannelAction: @@ -143,8 +171,10 @@ func (tr *TestRun) runStep(step Step, verbose bool) { tr.assignConsumerPubKey(action, verbose) case slashThrottleDequeue: tr.waitForSlashThrottleDequeue(action, verbose) - case startHermesAction: - tr.startHermes(action, verbose) + case startRelayerAction: + tr.startRelayer(action, verbose) + case registerConsumerRewardDenomAction: + tr.registerConsumerRewardDenom(action, verbose) default: log.Fatalf("unknown action in testRun %s: %#v", tr.name, action) } diff --git a/tests/e2e/state.go b/tests/e2e/state.go index d1c6fb40ea..0c2573574f 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -16,17 +16,18 @@ import ( type State map[chainID]ChainState type ChainState struct { - ValBalances *map[validatorID]uint - Proposals *map[uint]Proposal - ValPowers *map[validatorID]uint - RepresentativePowers *map[validatorID]uint - Params *[]Param - Rewards *Rewards - ConsumerChains *map[chainID]bool - AssignedKeys *map[validatorID]string - ProviderKeys *map[validatorID]string // validatorID: validator provider key - ConsumerChainQueueSizes *map[chainID]uint - GlobalSlashQueueSize *uint + ValBalances *map[validatorID]uint + Proposals *map[uint]Proposal + ValPowers *map[validatorID]uint + RepresentativePowers *map[validatorID]uint + Params *[]Param + Rewards *Rewards + ConsumerChains *map[chainID]bool + AssignedKeys *map[validatorID]string + ProviderKeys *map[validatorID]string // validatorID: validator provider key + ConsumerChainQueueSizes *map[chainID]uint + GlobalSlashQueueSize *uint + RegisteredConsumerRewardDenoms *[]string } type Proposal interface { @@ -49,6 +50,17 @@ type ConsumerAdditionProposal struct { Status string } +type UpgradeProposal struct { + Title string + Description string + UpgradeHeight uint64 + Type string + Deposit uint + Status string +} + +func (p UpgradeProposal) isProposal() {} + func (p ConsumerAdditionProposal) isProposal() {} type ConsumerRemovalProposal struct { @@ -167,6 +179,11 @@ func (tr TestRun) getChainState(chain chainID, modelState ChainState) ChainState chainState.ConsumerChainQueueSizes = &consumerChainQueueSizes } + if modelState.RegisteredConsumerRewardDenoms != nil { + registeredConsumerRewardDenoms := tr.getRegisteredConsumerRewardDenoms(chain) + chainState.RegisteredConsumerRewardDenoms = ®isteredConsumerRewardDenoms + } + return chainState } @@ -193,6 +210,16 @@ func (tr TestRun) getBlockHeight(chain chainID) uint { } func (tr TestRun) waitBlocks(chain chainID, blocks uint, timeout time.Duration) { + if tr.useCometmock { + // call advance_blocks method on cometmock + // curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"advance_blocks","params":{"num_blocks": "36000000"},"id":1}' 127.0.0.1:22331 + tcpAddress := tr.getQueryNodeRPCAddress(chain) + method := "advance_blocks" + params := fmt.Sprintf(`{"num_blocks": "%d"}`, blocks) + + tr.curlJsonRPCRequest(method, params, tcpAddress) + return + } startBlock := tr.getBlockHeight(chain) start := time.Now() @@ -208,6 +235,20 @@ func (tr TestRun) waitBlocks(chain chainID, blocks uint, timeout time.Duration) } } +func (tr TestRun) waitUntilBlock(chain chainID, block uint, timeout time.Duration) { + start := time.Now() + for { + thisBlock := tr.getBlockHeight(chain) + if thisBlock >= block { + return + } + if time.Since(start) > timeout { + panic(fmt.Sprintf("\n\n\nwaitBlocks method has timed out after: %s\n\n", timeout)) + } + time.Sleep(500 * time.Millisecond) + } +} + func (tr TestRun) getBalances(chain chainID, modelState map[validatorID]uint) map[validatorID]uint { actualState := map[validatorID]uint{} for k := range modelState { @@ -384,6 +425,16 @@ func (tr TestRun) getProposal(chain chainID, proposal uint) Proposal { RevisionHeight: gjson.Get(string(bz), `messages.0.content.initial_height.revision_height`).Uint(), }, } + case "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal": + height := gjson.Get(string(bz), `content.plan.height`).Uint() + title := gjson.Get(string(bz), `content.plan.name`).String() + return UpgradeProposal{ + Deposit: uint(deposit), + Status: status, + UpgradeHeight: height, + Title: title, + Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + } case "/interchain_security.ccv.provider.v1.ConsumerRemovalProposal": chainId := gjson.Get(string(bz), `messages.0.content.chain_id`).String() stopTime := gjson.Get(string(bz), `messages.0.content.stop_time`).Time().Sub(tr.containerConfig.now) @@ -641,7 +692,34 @@ func (tr TestRun) getConsumerChainPacketQueueSize(consumerChain chainID) uint { return uint(size) } +func (tr TestRun) getRegisteredConsumerRewardDenoms(chain chainID) []string { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, tr.chainConfigs[chain].binaryName, + + "query", "provider", "registered-consumer-reward-denoms", + `--node`, tr.getQueryNode(chain), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + denoms := gjson.Get(string(bz), "denoms").Array() + rewardDenoms := make([]string, len(denoms)) + for i, d := range denoms { + rewardDenoms[i] = d.String() + } + + return rewardDenoms +} + func (tr TestRun) getValidatorNode(chain chainID, validator validatorID) string { + // for CometMock, validatorNodes are all the same address as the query node (which is CometMocks address) + if tr.useCometmock { + return tr.getQueryNode(chain) + } + return "tcp://" + tr.getValidatorIP(chain, validator) + ":26658" } @@ -655,11 +733,32 @@ func (tr TestRun) getValidatorHome(chain chainID, validator validatorID) string // getQueryNode returns query node tcp address on chain. func (tr TestRun) getQueryNode(chain chainID) string { - return fmt.Sprintf("tcp://%s:26658", tr.getQueryNodeIP(chain)) + return fmt.Sprintf("tcp://%s", tr.getQueryNodeRPCAddress(chain)) +} + +func (tr TestRun) getQueryNodeRPCAddress(chain chainID) string { + return fmt.Sprintf("%s:26658", tr.getQueryNodeIP(chain)) } // getQueryNodeIP returns query node IP for chain, -// ipSuffix is hardcoded to be 253 on all query nodes. +// ipSuffix is hardcoded to be 253 on all query nodes +// except for "sover" chain where there's only one node func (tr TestRun) getQueryNodeIP(chain chainID) string { + if chain == chainID("sover") { + // return address of first and only validator + return fmt.Sprintf("%s.%s", + tr.chainConfigs[chain].ipPrefix, + tr.validatorConfigs[validatorID("alice")].ipSuffix) + } return fmt.Sprintf("%s.253", tr.chainConfigs[chain].ipPrefix) } + +func (tr TestRun) curlJsonRPCRequest(method, params, address string) { + cmd_template := `curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}' %s` + + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + cmd := exec.Command("docker", "exec", tr.containerConfig.instanceName, "bash", "-c", fmt.Sprintf(cmd_template, method, params, address)) + + verbosity := false + executeCommandWithVerbosity(cmd, "curlJsonRPCRequest", verbosity) +} diff --git a/tests/e2e/step_delegation.go b/tests/e2e/step_delegation.go index dfcfebc755..b6e7c8ad76 100644 --- a/tests/e2e/step_delegation.go +++ b/tests/e2e/step_delegation.go @@ -46,7 +46,8 @@ func stepsDelegate(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -110,7 +111,8 @@ func stepsUnbond(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -158,7 +160,8 @@ func stepsCancelUnbond(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -199,7 +202,8 @@ func stepsCancelUnbond(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -249,7 +253,8 @@ func stepsRedelegateForOptOut(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -301,7 +306,61 @@ func stepsRedelegate(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 0, + }, + state: State{ + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + // Now power changes are seen by consumer + validatorID("alice"): 509, + validatorID("bob"): 500, + validatorID("carol"): 501, + }, + }, + }, + }, + } +} + +// stepsRedelegate tests redelegation and resulting validator power changes. +func stepsRedelegateShort(consumerName string) []Step { + return []Step{ + { + action: redelegateTokensAction{ + chain: chainID("provi"), + src: validatorID("alice"), + dst: validatorID("carol"), + txSender: validatorID("alice"), + // Leave alice with majority stake so non-faulty validators maintain more than + // 2/3 voting power during downtime tests below, avoiding chain halt + amount: 1000000, + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 509, + validatorID("bob"): 500, + // carol always uses a consumer assigned key + validatorID("carol"): 501, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + // Voting power changes not seen by consumer yet + validatorID("alice"): 510, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index a74cfaab4e..aa08426103 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -26,11 +26,22 @@ var happyPathSteps = concatSteps( stepsRejectEquivocationProposal("consu", 2), // prop to tombstone bob is rejected stepsDoubleSignOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer stepsSubmitEquivocationProposal("consu", 2), // now prop to tombstone bob is submitted and accepted - stepsStartHermes(), + stepsStartRelayer(), stepsConsumerRemovalPropNotPassing("consu", 3), // submit removal prop but vote no on it - chain should stay stepsStopChain("consu", 4), // stop chain ) +var shortHappyPathSteps = concatSteps( + stepsStartChains([]string{"consu"}, false), + stepsDelegate("consu"), + stepsUnbond("consu"), + stepsRedelegateShort("consu"), + stepsDowntime("consu"), + stepsStartRelayer(), + stepsConsumerRemovalPropNotPassing("consu", 2), // submit removal prop but vote no on it - chain should stay + stepsStopChain("consu", 3), // stop chain +) + var slashThrottleSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), @@ -46,6 +57,14 @@ var democracySteps = concatSteps( stepsDemocracy("democ"), ) +var rewardDenomConsumerSteps = concatSteps( + // democracySteps requires a transfer channel + stepsStartChains([]string{"democ"}, true), + // delegation needs to happen so the first VSC packet can be delivered + stepsDelegate("democ"), + stepsRewardDenomConsumer("democ"), +) + var multipleConsumers = concatSteps( stepsStartChains([]string{"consu", "densu"}, false), stepsMultiConsumerDelegate("consu", "densu"), @@ -55,3 +74,18 @@ var multipleConsumers = concatSteps( stepsMultiConsumerDowntimeFromProvider("consu", "densu"), stepsMultiConsumerDoubleSign("consu", "densu"), // double sign on one of the chains ) + +var changeoverSteps = concatSteps( + // start sovereign chain and test delegation operation + + stepRunSovereignChain(), + stepStartProviderChain(), + stepsSovereignTransferChan(), + + // the chain will halt once upgrade height is reached + // after upgrade height is reached, the chain will become a consumer + stepsUpgradeChain(), + stepsChangeoverToConsumer("sover"), + + stepsPostChangeoverDelegate("sover"), +) diff --git a/tests/e2e/steps_democracy.go b/tests/e2e/steps_democracy.go index 98e5ec6e06..3c80818a24 100644 --- a/tests/e2e/steps_democracy.go +++ b/tests/e2e/steps_democracy.go @@ -1,5 +1,7 @@ package main +const consumerRewardDenom = "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" + func stepsDemocracy(consumerName string) []Step { return []Step{ { @@ -106,6 +108,47 @@ func stepsDemocracy(consumerName string) []Step { }, }, }, + { + action: relayRewardPacketsToProviderAction{ + consumerChain: chainID(consumerName), + providerChain: chainID("provi"), + port: "transfer", + channel: 1, + }, + state: State{ + chainID("provi"): ChainState{ + // Check that tokens are not distributed before the denom has been registered + Rewards: &Rewards{ + IsRewarded: map[validatorID]bool{ + validatorID("alice"): false, + validatorID("bob"): false, + validatorID("carol"): false, + }, + IsIncrementalReward: false, + IsNativeDenom: false, + }, + // Check that the denom is not registered on provider chain + RegisteredConsumerRewardDenoms: &[]string{}, + }, + }, + }, + { + action: registerConsumerRewardDenomAction{ + chain: chainID("provi"), + from: validatorID("bob"), + denom: consumerRewardDenom, + }, + state: State{ + chainID("provi"): ChainState{ + // Check that the denom is registered on provider chain + RegisteredConsumerRewardDenoms: &[]string{consumerRewardDenom}, + ValBalances: &map[validatorID]uint{ + // make sure that bob's account was debited + validatorID("bob"): 9490000000, + }, + }, + }, + }, { action: relayRewardPacketsToProviderAction{ consumerChain: chainID(consumerName), @@ -153,7 +196,8 @@ func stepsDemocracy(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -179,7 +223,8 @@ func stepsDemocracy(consumerName string) []Step { // and can now be relayed as packet to consumer { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -218,7 +263,8 @@ func stepsDemocracy(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/steps_double_sign.go b/tests/e2e/steps_double_sign.go index e4efca4bb5..c007fa5c1c 100644 --- a/tests/e2e/steps_double_sign.go +++ b/tests/e2e/steps_double_sign.go @@ -30,7 +30,8 @@ func stepsDoubleSignOnProviderAndConsumer(consumerName string) []Step { { // relay power change to consumerName action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, // consumerName channel }, @@ -78,7 +79,8 @@ func stepsDoubleSignOnProviderAndConsumer(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -102,7 +104,8 @@ func stepsDoubleSignOnProviderAndConsumer(consumerName string) []Step { { // consumer learns about the double sign action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index af2d2f237e..74cb349000 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -39,7 +39,8 @@ func stepsDowntime(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -65,7 +66,8 @@ func stepsDowntime(consumerName string) []Step { // and can now be relayed as packet to consumer { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -106,7 +108,8 @@ func stepsDowntime(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -150,7 +153,8 @@ func stepsDowntime(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -188,7 +192,8 @@ func stepsDowntime(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -236,7 +241,8 @@ func stepsDowntimeWithOptOut(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -314,7 +320,8 @@ func stepsThrottledDowntime(consumerName string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, @@ -376,7 +383,8 @@ func stepsThrottledDowntime(consumerName string) []Step { // and can now be relayed as packet to consumer { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/steps_multi_consumer_delegation.go b/tests/e2e/steps_multi_consumer_delegation.go index 106307629d..45536c0679 100644 --- a/tests/e2e/steps_multi_consumer_delegation.go +++ b/tests/e2e/steps_multi_consumer_delegation.go @@ -38,7 +38,8 @@ func stepsMultiConsumerDelegate(consumer1, consumer2 string) []Step { { // relay changes to consumer1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -69,7 +70,8 @@ func stepsMultiConsumerDelegate(consumer1, consumer2 string) []Step { { // relay changes to consumer2 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, @@ -138,7 +140,8 @@ func stepsMultiConsumerUnbond(consumer1, consumer2 string) []Step { { // relay to consumer1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -169,7 +172,8 @@ func stepsMultiConsumerUnbond(consumer1, consumer2 string) []Step { { // relay to consumer2 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, @@ -242,7 +246,8 @@ func stepsMultiConsumerRedelegate(consumer1, consumer2 string) []Step { { // relay to consumer1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -273,7 +278,8 @@ func stepsMultiConsumerRedelegate(consumer1, consumer2 string) []Step { { // relay to consumer2 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer1 channel }, diff --git a/tests/e2e/steps_multi_consumer_double_sign.go b/tests/e2e/steps_multi_consumer_double_sign.go index a50f21e11f..d12eb37eff 100644 --- a/tests/e2e/steps_multi_consumer_double_sign.go +++ b/tests/e2e/steps_multi_consumer_double_sign.go @@ -45,7 +45,8 @@ func stepsMultiConsumerDoubleSign(consumer1, consumer2 string) []Step { { // relay power change to consumer1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -76,7 +77,8 @@ func stepsMultiConsumerDoubleSign(consumer1, consumer2 string) []Step { { // relay power change to consumer2 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, @@ -137,7 +139,8 @@ func stepsMultiConsumerDoubleSign(consumer1, consumer2 string) []Step { }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -168,7 +171,8 @@ func stepsMultiConsumerDoubleSign(consumer1, consumer2 string) []Step { { // consumer1 learns about the double sign action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -199,7 +203,8 @@ func stepsMultiConsumerDoubleSign(consumer1, consumer2 string) []Step { { // consumer2 learns about the double sign action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, diff --git a/tests/e2e/steps_multi_consumer_downtime.go b/tests/e2e/steps_multi_consumer_downtime.go index 181ced029f..ce6cbdff59 100644 --- a/tests/e2e/steps_multi_consumer_downtime.go +++ b/tests/e2e/steps_multi_consumer_downtime.go @@ -40,7 +40,8 @@ func stepsMultiConsumerDowntimeFromConsumer(consumer1, consumer2 string) []Step // Downtime jailing and corresponding voting power change are processed by provider // Validator powers are unchanged on consumer chains action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, }, @@ -73,7 +74,8 @@ func stepsMultiConsumerDowntimeFromConsumer(consumer1, consumer2 string) []Step // and can now be relayed as packet to consumer // consumer1 will now see the validator power changes - consumer2 will not (had not been relayed) action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 chan }, @@ -100,7 +102,8 @@ func stepsMultiConsumerDowntimeFromConsumer(consumer1, consumer2 string) []Step { // both consumer1 and consumer will now see the validator power changes action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 chan }, @@ -156,7 +159,8 @@ func stepsMultiConsumerDowntimeFromConsumer(consumer1, consumer2 string) []Step { // relay to consumer 1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, }, @@ -187,7 +191,8 @@ func stepsMultiConsumerDowntimeFromConsumer(consumer1, consumer2 string) []Step { // relay to consumer2 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 chan }, @@ -255,7 +260,8 @@ func stepsMultiConsumerDowntimeFromProvider(consumer1, consumer2 string) []Step }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer 1 channel }, @@ -288,7 +294,8 @@ func stepsMultiConsumerDowntimeFromProvider(consumer1, consumer2 string) []Step }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, @@ -349,7 +356,8 @@ func stepsMultiConsumerDowntimeFromProvider(consumer1, consumer2 string) []Step }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer1), port: "provider", channel: 0, // consumer1 channel }, @@ -380,7 +388,8 @@ func stepsMultiConsumerDowntimeFromProvider(consumer1, consumer2 string) []Step }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumer2), port: "provider", channel: 1, // consumer2 channel }, diff --git a/tests/e2e/steps_reward_denom.go b/tests/e2e/steps_reward_denom.go new file mode 100644 index 0000000000..cb557f0471 --- /dev/null +++ b/tests/e2e/steps_reward_denom.go @@ -0,0 +1,285 @@ +package main + +func stepsRewardDenomConsumer(consumerName string) []Step { + return []Step{ + { + action: registerRepresentativeAction{ + chain: chainID(consumerName), + representatives: []validatorID{validatorID("alice"), validatorID("bob")}, + stakes: []uint{100000000, 40000000}, + }, + state: State{ + chainID(consumerName): ChainState{ + RepresentativePowers: &map[validatorID]uint{ + validatorID("alice"): 100000000, + validatorID("bob"): 40000000, + }, + Rewards: &Rewards{ + IsRewarded: map[validatorID]bool{ + validatorID("alice"): true, + validatorID("bob"): true, + validatorID("carol"): false, + }, + IsIncrementalReward: true, + IsNativeDenom: true, + }, + }, + }, + }, + { + action: delegateTokensAction{ + chain: chainID(consumerName), + from: validatorID("carol"), + to: validatorID("alice"), + amount: 500000, + }, + state: State{ + chainID(consumerName): ChainState{ + // Check that delegators on gov-consumer chain can change representative powers + RepresentativePowers: &map[validatorID]uint{ + validatorID("alice"): 100500000, + validatorID("bob"): 40000000, + }, + // Check that delegating on gov-consumer does not change validator powers + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + // Check that tokens are minted and distributed to representatives and their delegators + Rewards: &Rewards{ + IsRewarded: map[validatorID]bool{ + validatorID("alice"): true, + validatorID("bob"): true, + validatorID("carol"): true, + }, + IsIncrementalReward: true, + IsNativeDenom: true, + }, + }, + }, + }, + { + // whitelisted legacy proposal can only handle ibctransfer.SendEnabled/ReceiveEnabled + action: submitParamChangeLegacyProposalAction{ + chain: chainID(consumerName), + from: validatorID("alice"), + deposit: 10000001, + subspace: "transfer", + key: "SendEnabled", + value: true, + }, + state: State{ + chainID(consumerName): ChainState{ + ValBalances: &map[validatorID]uint{ + validatorID("alice"): 9889999998, + validatorID("bob"): 9960000001, + }, + Proposals: &map[uint]Proposal{ + 1: ParamsProposal{ + Deposit: 10000001, + Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Subspace: "transfer", + Key: "SendEnabled", + Value: "true", + }, + }, + }, + }, + }, + { + // Have accounts vote on something on the gov-consumer chain + action: voteGovProposalAction{ + chain: chainID(consumerName), + from: []validatorID{validatorID("alice"), validatorID("bob")}, + vote: []string{"yes", "no"}, + propNumber: 1, + }, + state: State{ + chainID(consumerName): ChainState{ + ValBalances: &map[validatorID]uint{ + validatorID("alice"): 9899999999, + validatorID("bob"): 9960000001, + }, + // Check that the parameter is changed on gov-consumer chain + Params: &([]Param{{Subspace: "staking", Key: "MaxValidators", Value: "105"}}), + }, + }, + }, + { + action: relayRewardPacketsToProviderAction{ + consumerChain: chainID(consumerName), + providerChain: chainID("provi"), + port: "transfer", + channel: 1, + }, + state: State{ + chainID("provi"): ChainState{ + // Check that tokens are not distributed before the denom has been registered + Rewards: &Rewards{ + IsRewarded: map[validatorID]bool{ + validatorID("alice"): false, + validatorID("bob"): false, + validatorID("carol"): false, + }, + IsIncrementalReward: false, + IsNativeDenom: false, + }, + // Check that the denom is not registered on provider chain + RegisteredConsumerRewardDenoms: &[]string{}, + }, + }, + }, + { + action: registerConsumerRewardDenomAction{ + chain: chainID("provi"), + from: validatorID("bob"), + denom: "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9", + }, + state: State{ + chainID("provi"): ChainState{ + // Check that the denom is registered on provider chain + RegisteredConsumerRewardDenoms: &[]string{"ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9"}, + ValBalances: &map[validatorID]uint{ + // make sure that bob's account was debited + validatorID("bob"): 9490000000, + }, + }, + }, + }, + { + action: relayRewardPacketsToProviderAction{ + consumerChain: chainID(consumerName), + providerChain: chainID("provi"), + port: "transfer", + channel: 1, + }, + state: State{ + chainID("provi"): ChainState{ + // Check that tokens are not minted and sent to provider chain and distributed to validators and their delegators on provider chain + Rewards: &Rewards{ + IsRewarded: map[validatorID]bool{ + validatorID("alice"): false, + validatorID("bob"): false, + validatorID("carol"): false, + }, + IsIncrementalReward: false, + IsNativeDenom: false, + }, + }, + }, + }, + { + action: downtimeSlashAction{ + chain: chainID(consumerName), + validator: validatorID("bob"), + }, + state: State{ + // validator should be slashed on consumer, powers not affected on either chain yet + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 0, + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + // Downtime jailing and corresponding voting power change are processed by provider + validatorID("bob"): 0, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + // A block is incremented each action, hence why VSC is committed on provider, + // and can now be relayed as packet to consumer + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 0, + }, + state: State{ + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + // VSC now seen on consumer + validatorID("bob"): 0, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: unjailValidatorAction{ + provider: chainID("provi"), + validator: validatorID("bob"), + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 0, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 0, + }, + state: State{ + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + // Check that slashing on the gov-consumer chain does not result in slashing for the representatives or their delegators + RepresentativePowers: &map[validatorID]uint{ + validatorID("alice"): 100500000, + validatorID("bob"): 40000000, + }, + }, + }, + }, + } +} diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go new file mode 100644 index 0000000000..71daad684b --- /dev/null +++ b/tests/e2e/steps_sovereign_changeover.go @@ -0,0 +1,367 @@ +package main + +import clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + +// this creates new clients on both chains and a connection (connection-0) between them +// connection-0 is used to create a transfer channel between the chains +// the transfer channel is maintained during the changeover process, meaning that +// the consumer chain will be able to send rewards to the provider chain using the old channel +// as opposed to creating a new transfer channel which happens for new consumers +func stepsSovereignTransferChan() []Step { + return []Step{ + { + action: createIbcClientsAction{ + chainA: chainID("sover"), + chainB: chainID("provi"), + }, + state: State{}, + }, + { + // this will create channel-0 connection end on both chain + action: addIbcChannelAction{ + chainA: chainID("sover"), + chainB: chainID("provi"), + connectionA: 0, + portA: "transfer", + portB: "transfer", + order: "unordered", + version: "ics20-1", + }, + state: State{}, + }, + } +} + +// steps to convert sovereign to consumer chain +func stepsChangeoverToConsumer(consumerName string) []Step { + s := []Step{ + { + action: submitConsumerAdditionProposalAction{ + preCCV: true, + chain: chainID("provi"), + from: validatorID("alice"), + deposit: 10000001, + consumerChain: chainID(consumerName), + // chain-0 is the transfer channelID that gets created in stepsSovereignTransferChan + // the consumer chain will use this channel to send rewards to the provider chain + // there is no need to create a new channel for rewards distribution + distributionChannel: "channel-0", + spawnTime: 0, + initialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, // 1 block after upgrade !important + }, + state: State{ + chainID("provi"): ChainState{ + ValBalances: &map[validatorID]uint{ + validatorID("alice"): 9489999999, + validatorID("bob"): 9500000000, + }, + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: chainID(consumerName), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, + Status: "PROPOSAL_STATUS_VOTING_PERIOD", + }, + }, + }, + }, + }, + { + action: voteGovProposalAction{ + chain: chainID("provi"), + from: []validatorID{validatorID("alice"), validatorID("bob"), validatorID("carol")}, + vote: []string{"yes", "yes", "yes"}, + propNumber: 1, + }, + state: State{ + chainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: chainID(consumerName), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, + Status: "PROPOSAL_STATUS_PASSED", + }, + }, + ValBalances: &map[validatorID]uint{ + validatorID("alice"): 9500000000, + validatorID("bob"): 9500000000, + }, + }, + }, + }, + { + action: ChangeoverChainAction{ + sovereignChain: chainID(consumerName), + providerChain: chainID("provi"), + validators: []StartChainValidator{ + {id: validatorID("alice"), stake: 500000000, allocation: 10000000000}, + {id: validatorID("bob"), stake: 500000000, allocation: 10000000000}, + {id: validatorID("carol"), stake: 500000000, allocation: 10000000000}, + }, + genesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 500, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + // uses val powers from consumer + validatorID("alice"): 500, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: addIbcConnectionAction{ + chainA: chainID(consumerName), + chainB: chainID("provi"), + clientA: 1, + clientB: 1, + }, + state: State{}, + }, + { + action: addIbcChannelAction{ + chainA: chainID(consumerName), + chainB: chainID("provi"), + connectionA: 1, + portA: "consumer", + portB: "provider", + order: "ordered", + }, + state: State{}, + }, + } + + return s +} + +// start sovereign chain with a single validator so it is easier to manage +// when the chain is converted to a consumer chain the validators from the +// consumer chain will be used +// validatoralice is the only validator on the sovereign chain that is in both +// sovereign validator set and consumer validator set +func stepRunSovereignChain() []Step { + return []Step{ + { + action: StartSovereignChainAction{ + chain: chainID("sover"), + validators: []StartChainValidator{ + {id: validatorID("alice"), stake: 500000000, allocation: 10000000000}, + }, + }, + state: State{ + chainID("sover"): ChainState{ + ValBalances: &map[validatorID]uint{ + validatorID("alice"): 9500000000, + }, + }, + }, + }, + { + action: delegateTokensAction{ + chain: chainID("sover"), + from: validatorID("alice"), + to: validatorID("alice"), + amount: 11000000, + }, + state: State{ + chainID("sover"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 0, // does not exist on pre-ccv sover + validatorID("carol"): 0, // does not exist on pre-ccv sover + }, + }, + }, + }, + } +} + +// TODO: use args instead of hardcoding +func stepsUpgradeChain() []Step { + return []Step{ + { + action: UpgradeProposalAction{ + chainID: chainID("sover"), + upgradeTitle: "sovereign-changeover", + proposer: validatorID("alice"), + upgradeHeight: 110, + }, + state: State{ + chainID("sover"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: UpgradeProposal{ + Title: "sovereign-changeover", + UpgradeHeight: 110, + Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + Deposit: 10000000, + Status: "PROPOSAL_STATUS_VOTING_PERIOD", + }, + }, + }, + }, + }, + { + action: voteGovProposalAction{ + chain: chainID("sover"), + from: []validatorID{validatorID("alice")}, + vote: []string{"yes"}, + propNumber: 1, + }, + state: State{ + chainID("sover"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: UpgradeProposal{ + Deposit: 10000000, + UpgradeHeight: 110, + Title: "sovereign-changeover", + Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + Status: "PROPOSAL_STATUS_PASSED", + }, + }, + }, + }, + }, + { + action: waitUntilBlockAction{ + chain: chainID("sover"), + block: 110, + }, + state: State{}, + }, + } +} + +// stepsPostChangeoverDelegate tests basic delegation and resulting validator power changes after changeover +// we cannot use stepsDelegate and stepsUnbond because they make assumptions about which connection to use +// here we need to use connection-1, and in tests with new consumers connection-0 is used because the chain is new (has no IBC states prior to launch) +func stepsPostChangeoverDelegate(consumerName string) []Step { + return []Step{ + { + action: SendTokensAction{ + chain: chainID(consumerName), + from: validatorID("alice"), + to: validatorID("bob"), + amount: 100, + }, + state: State{ + chainID(consumerName): ChainState{ + // Tx should not go through, ICS channel is not setup until first VSC packet has been relayed to consumer + ValBalances: &map[validatorID]uint{ + validatorID("bob"): 0, + }, + }, + }, + }, + { + action: delegateTokensAction{ + chain: chainID("provi"), + from: validatorID("alice"), + to: validatorID("alice"), + amount: 11000000, + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 500, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 1, + }, + state: State{ + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: SendTokensAction{ + chain: chainID(consumerName), + from: validatorID("alice"), + to: validatorID("bob"), + amount: 100, + }, + state: State{ + chainID(consumerName): ChainState{ + // Tx should go through, ICS channel is setup + ValBalances: &map[validatorID]uint{ + validatorID("bob"): 100, + }, + }, + }, + }, + { + action: unbondTokensAction{ + chain: chainID("provi"), + unbondFrom: validatorID("alice"), + sender: validatorID("alice"), + amount: 1000000, + }, + state: State{ + chainID("provi"): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 510, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + // Voting power on consumer should not be affected yet + validatorID("alice"): 511, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + { + action: relayPacketsAction{ + chainA: chainID("provi"), + chainB: chainID(consumerName), + port: "provider", + channel: 1, + }, + state: State{ + chainID(consumerName): ChainState{ + ValPowers: &map[validatorID]uint{ + validatorID("alice"): 510, + validatorID("bob"): 500, + validatorID("carol"): 500, + }, + }, + }, + }, + } +} diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index 1a2aba229b..15d0045760 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -265,7 +265,8 @@ func stepsAssignConsumerKeyOnStartedChain(consumerName, validator string) []Step }, { action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/steps_stop_chain.go b/tests/e2e/steps_stop_chain.go index 229b40b215..9cef49a9ea 100644 --- a/tests/e2e/steps_stop_chain.go +++ b/tests/e2e/steps_stop_chain.go @@ -2,11 +2,11 @@ package main import "time" -// start hermes so that all messages are relayed -func stepsStartHermes() []Step { +// start relayer so that all messages are relayed +func stepsStartRelayer() []Step { return []Step{ { - action: startHermesAction{}, + action: startRelayerAction{}, state: State{}, }, } diff --git a/tests/e2e/steps_submit_equivocation_proposal.go b/tests/e2e/steps_submit_equivocation_proposal.go index f8a91d5362..8af1d2464d 100644 --- a/tests/e2e/steps_submit_equivocation_proposal.go +++ b/tests/e2e/steps_submit_equivocation_proposal.go @@ -122,7 +122,8 @@ func stepsSubmitEquivocationProposal(consumerName string, propNumber uint) []Ste { // relay power change to consumer1 action: relayPacketsAction{ - chain: chainID("provi"), + chainA: chainID("provi"), + chainB: chainID(consumerName), port: "provider", channel: 0, }, diff --git a/tests/e2e/testnet-scripts/sovereign-genesis.json b/tests/e2e/testnet-scripts/sovereign-genesis.json new file mode 100644 index 0000000000..6c34a0ec1c --- /dev/null +++ b/tests/e2e/testnet-scripts/sovereign-genesis.json @@ -0,0 +1,281 @@ +{ + "genesis_time": "2023-06-19T21:06:09.696739416Z", + "chain_id": "sover", + "initial_height": "1", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "1048576" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + }, + "version": { + "app": "0" + } + }, + "app_hash": "", + "app_state": { + "07-tendermint": null, + "auth": { + "params": { + "max_memo_characters": "256", + "tx_sig_limit": "7", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "590", + "sig_verify_cost_secp256k1": "1000" + }, + "accounts": [ + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la", + "pub_key": null, + "account_number": "0", + "sequence": "0" + } + ] + }, + "bank": { + "params": { + "send_enabled": [], + "default_send_enabled": true + }, + "balances": [ + { + "address": "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", + "coins": [ + { + "denom": "stake", + "amount": "10000000000" + } + ] + } + ], + "supply": [ + { + "denom": "stake", + "amount": "10000000000" + } + ], + "denom_metadata": [], + "send_enabled": [] + }, + "capability": { + "index": "1", + "owners": [] + }, + "crisis": { + "constant_fee": { + "denom": "stake", + "amount": "1000" + } + }, + "distribution": { + "params": { + "community_tax": "0.020000000000000000", + "base_proposer_reward": "0.000000000000000000", + "bonus_proposer_reward": "0.000000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [] + }, + "delegator_withdraw_infos": [], + "previous_proposer": "", + "outstanding_rewards": [], + "validator_accumulated_commissions": [], + "validator_historical_rewards": [], + "validator_current_rewards": [], + "delegator_starting_infos": [], + "validator_slash_events": [] + }, + "evidence": { + "evidence": [] + }, + "genutil": { + "gen_txs": [ + { + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", + "description": { + "moniker": "validatoralice", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "commission": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", + "validator_address": "cosmosvaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtrgtng", + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "RrclQz9bIhkIy/gfL485g3PYMeiIku4qeo495787X10=" + }, + "value": { + "denom": "stake", + "amount": "500000000" + } + } + ], + "memo": "8339e14baab81c2a2350e261962263397a8d7fb0@7.7.7.254:26656", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "AsFC8tmbGGQSHthsVStbsQ13/+Yza9IT8KCSXXEN7y9f" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + }, + "tip": null + }, + "signatures": [ + "D06i2qqq2HathlT7cy+PDLTDuYKAmzw5Ne+Ehvzr9bVy3jpm2h8deDGeSXTSrhdP04UpFXerSn+zIPth5TKNrg==" + ] + } + ] + }, + "gov": { + "starting_proposal_id": "1", + "deposits": [], + "votes": [], + "proposals": [], + "deposit_params": null, + "voting_params": null, + "tally_params": null, + "params": { + "min_deposit": [ + { + "denom": "stake", + "amount": "10000000" + } + ], + "max_deposit_period": "172800s", + "voting_period": "20s", + "quorum": "0.334000000000000000", + "threshold": "0.500000000000000000", + "veto_threshold": "0.334000000000000000", + "min_initial_deposit_ratio": "0.000000000000000000", + "burn_vote_quorum": false, + "burn_proposal_deposit_prevote": false, + "burn_vote_veto": true + } + }, + "ibc": { + "client_genesis": { + "clients": [], + "clients_consensus": [], + "clients_metadata": [], + "params": { + "allowed_clients": [ + "06-solomachine", + "07-tendermint" + ] + }, + "create_localhost": false, + "next_client_sequence": "0" + }, + "connection_genesis": { + "connections": [], + "client_connection_paths": [], + "next_connection_sequence": "0", + "params": { + "max_expected_time_per_block": "30000000000" + } + }, + "channel_genesis": { + "channels": [], + "acknowledgements": [], + "commitments": [], + "receipts": [], + "send_sequences": [], + "recv_sequences": [], + "ack_sequences": [], + "next_channel_sequence": "0" + } + }, + "mint": { + "minter": { + "inflation": "0.130000000000000000", + "annual_provisions": "0.000000000000000000" + }, + "params": { + "mint_denom": "stake", + "inflation_rate_change": "0.130000000000000000", + "inflation_max": "0.200000000000000000", + "inflation_min": "0.070000000000000000", + "goal_bonded": "0.670000000000000000", + "blocks_per_year": "6311520" + } + }, + "params": null, + "slashing": { + "params": { + "signed_blocks_window": "10", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "60s", + "slash_fraction_double_sign": "0.050000000000000000", + "slash_fraction_downtime": "0.010000000000000000" + }, + "signing_infos": [], + "missed_blocks": [] + }, + "staking": { + "params": { + "unbonding_time": "1814400s", + "max_validators": 100, + "max_entries": 7, + "historical_entries": 10000, + "bond_denom": "stake", + "min_commission_rate": "0.000000000000000000" + }, + "last_total_power": "0", + "last_validator_powers": [], + "validators": [], + "delegations": [], + "unbonding_delegations": [], + "redelegations": [], + "exported": false + }, + "transfer": { + "port_id": "transfer", + "denom_traces": [], + "params": { + "send_enabled": true, + "receive_enabled": true + } + }, + "upgrade": {}, + "vesting": {} + } +} \ No newline at end of file diff --git a/tests/e2e/testnet-scripts/start-chain.sh b/tests/e2e/testnet-scripts/start-chain.sh index acf53157cb..a3609acf73 100644 --- a/tests/e2e/testnet-scripts/start-chain.sh +++ b/tests/e2e/testnet-scripts/start-chain.sh @@ -33,6 +33,18 @@ SKIP_GENTX=$6 # A sed string modifying the tendermint config TENDERMINT_CONFIG_TRANSFORM=$7 +# whether to use CometMock +USE_COMETMOCK=$8 + +# stores a comma separated list of nodes addresses +# needed for CometMock - these are the addresses that the ABCI servers of the apps are listening on +NODE_LISTEN_ADDR_STR="" # example value: 7.7.8.6:26655,7.7.8.4:26655,7.7.8.5:26655 + +# stores a comma separated list of nodes home folders +# needed for CometMock - validator nodes have their private keys in their home directories, and CometMock +# reads the keys to sign with from there +NODE_HOMES="" # example value: /consu/validatorcarol,/consu/validatoralice,/consu/validatorbob + # CREATE VALIDATORS AND DO GENESIS CEREMONY @@ -219,10 +231,13 @@ do VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$i].ip_suffix") NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" - GAIA_HOME="--home /$CHAIN_ID/validator$VAL_ID" + NODE_HOME="/$CHAIN_ID/validator$VAL_ID" + GAIA_HOME="--home $NODE_HOME" + NODE_HOMES="$NODE_HOME,$NODE_HOMES" RPC_ADDRESS="--rpc.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" GRPC_ADDRESS="--grpc.address $CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:9091" LISTEN_ADDRESS="--address tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655" + NODE_LISTEN_ADDR_STR="$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655,$NODE_LISTEN_ADDR_STR" P2P_ADDRESS="--p2p.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26656" # LOG_LEVEL="--log_level trace" # switch to trace to see panic messages and rich and all debug msgs LOG_LEVEL="--log_level info" @@ -246,7 +261,13 @@ do PERSISTENT_PEERS="--p2p.persistent_peers ${PERSISTENT_PEERS:1}" ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC $PERSISTENT_PEERS" - ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & + if [[ "$USE_COMETMOCK" == "true" ]]; then + # to start with CometMock, ensure ABCI server uses grpc (--transport=grpc) and the app is started without in-process CometBFT (--with-tendermint=false) + ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start --transport=grpc --with-tendermint=false &> /$CHAIN_ID/validator$VAL_ID/logs & + else + ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & + fi + done ## SETUP DOUBLE SIGNING NODE NETWORK NAMESPACE @@ -321,16 +342,46 @@ QUERY_PERSISTENT_PEERS="--p2p.persistent_peers ${QUERY_PERSISTENT_PEERS:1}" ## START NODE ARGS="$QUERY_GAIA_HOME $QUERY_LISTEN_ADDRESS $QUERY_RPC_ADDRESS $QUERY_GRPC_ADDRESS $QUERY_LOG_LEVEL $QUERY_P2P_ADDRESS $QUERY_ENABLE_WEBGRPC $QUERY_PERSISTENT_PEERS" -ip netns exec $QUERY_NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/$QUERY_NODE_ID/logs & + +# Query node is only started if CometMock is not used - with CometMock, it takes the role of the query node +if [[ "$USE_COMETMOCK" != "true" ]]; then + ip netns exec $QUERY_NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/$QUERY_NODE_ID/logs & +fi ## DONE START NODE +echo "Node addresses:" +echo $NODE_LISTEN_ADDR_STR + +echo "Node homes:" +echo $NODE_HOMES + +NODE_LISTEN_ADDR_STR=${NODE_LISTEN_ADDR_STR%?} +NODE_HOMES=${NODE_HOMES%?} + + +# CometMock takes the role of the query node +if [[ "$USE_COMETMOCK" == "true" ]]; then + sleep 2 + ip netns exec $QUERY_NET_NAMESPACE_NAME cometmock $NODE_LISTEN_ADDR_STR /$CHAIN_ID/genesis.json tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658 $NODE_HOMES &> cometmock_${CHAIN_ID}_out.log & + sleep 3 +fi + +# exit + # poll for chain start -set +e -until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done -set -e +if [[ "$USE_COMETMOCK" == "true" ]]; then + set +e + until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658"; do sleep 0.3 ; done + set -e +else + set +e + until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash": + ""}},"block":null}'; do sleep 0.3 ; done + set -e +fi echo "done!!!!!!!!" -read -p "Press Return to Close..." \ No newline at end of file +read -p "Press Return to Close..." diff --git a/tests/e2e/testnet-scripts/start-changeover.sh b/tests/e2e/testnet-scripts/start-changeover.sh new file mode 100644 index 0000000000..d28479a8e7 --- /dev/null +++ b/tests/e2e/testnet-scripts/start-changeover.sh @@ -0,0 +1,187 @@ +#!/bin/bash +set -eux + +# The gaiad binary +BIN=$1 + +# JSON array of validator information +# [{ +# mnemonic: "crackle snap pop ... etc", +# allocation: "10000000000stake,10000000000footoken", +# stake: "5000000000stake", +# val_id: "alice", +# ip_suffix: "1", +# priv_validator_key: "{\"address\": \"3566F464673B2F069758DAE86FC25D04017BB147\",\"pub_key\": {\"type\": \"tendermint/PubKeyEd25519\",\"value\": \"XrLjKdc4mB2gfqplvnoySjSJq2E90RynUwaO3WhJutk=\"},\"priv_key\": {\"type\": \"tendermint/PrivKeyEd25519\",\"value\": \"czGSLs/Ocau8aJ5J5zQHMxf3d7NR0xjMECN6YGTIWqtesuMp1ziYHaB+qmW+ejJKNImrYT3RHKdTBo7daEm62Q==\"}}" +# node_key: "{\"priv_key\":{\"type\":\"tendermint/PrivKeyEd25519\",\"value\":\"alIHj6hXnzpLAadgb7+E2eeecwxoNdzuZrfhMX36EaD5/LgzL0ZUoVp7AK3np0K5T35JWLLv0jJKmeRIhG0GjA==\"}}" +# }, ... ] +VALIDATORS=$2 + +# The chain ID +CHAIN_ID=$3 + +# This is the first 3 fields of the IP addresses which will be used internally by the validators of this blockchain +# Recommended to use something starting with 7, since it is squatted by the DoD and is unroutable on the internet +# For example: "7.7.7" +CHAIN_IP_PREFIX=$4 + +# A transformation to apply to the genesis file, as a jq string +GENESIS_TRANSFORM=$5 + +# A sed string modifying the tendermint config +TENDERMINT_CONFIG_TRANSFORM=$6 + + +# CREATE VALIDATORS AND DO GENESIS CEREMONY +# !!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!! # +# data dir from the sovereign chain is copied to other nodes (namely bob and carol) +# alice simply performs a chain upgrade +echo "killing nodes" +pkill -f "^"interchain-security-sd &> /dev/null || true + +mkdir -p /root/.sovereign/config + +# apply genesis changes to existing genesis -> this creates the changeover genesis file wih intial validator set +jq "$GENESIS_TRANSFORM" /sover/validatoralice/config/genesis.json > /root/.sovereign/config/genesis.json + + +# Get number of nodes from length of validators array +NODES=$(echo "$VALIDATORS" | jq '. | length') + +# SETUP NETWORK NAMESPACES, see: https://adil.medium.com/container-networking-under-the-hood-network-namespaces-6b2b8fe8dc2a + +# Create virtual bridge device (acts like a switch) +ip link add name virtual-bridge type bridge || true + +for i in $(seq 0 $(($NODES - 1))); +do + # first validator is already setup + if [[ "$i" -ne 0 ]]; then + VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") + VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$i].ip_suffix") + NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" + IP_ADDR="$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX/24" + + # Create network namespace + ip netns add $NET_NAMESPACE_NAME + # Create virtual ethernet device to connect with bridge + ip link add $NET_NAMESPACE_NAME-in type veth peer name $NET_NAMESPACE_NAME-out + # Connect input end of virtual ethernet device to namespace + ip link set $NET_NAMESPACE_NAME-in netns $NET_NAMESPACE_NAME + # Assign ip address to namespace + ip netns exec $NET_NAMESPACE_NAME ip addr add $IP_ADDR dev $NET_NAMESPACE_NAME-in + # Connect output end of virtual ethernet device to bridge + ip link set $NET_NAMESPACE_NAME-out master virtual-bridge + fi +done + +# Enable bridge interface +ip link set virtual-bridge up + +for i in $(seq 0 $(($NODES - 1))); +do + # first validator is already setup + if [[ "$i" -ne 0 ]]; then + VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") + NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" + + # Enable in/out interfaces for the namespace + ip link set $NET_NAMESPACE_NAME-out up + ip netns exec $NET_NAMESPACE_NAME ip link set dev $NET_NAMESPACE_NAME-in up + # Enable loopback device + ip netns exec $NET_NAMESPACE_NAME ip link set dev lo up + fi +done + +# Assign IP for bridge, to route between default network namespace and bridge +# BRIDGE_IP="$CHAIN_IP_PREFIX.254/24" +# ip addr add $BRIDGE_IP dev virtual-bridge + + +# HANDLE VALIDATOR HOMES, COPY OLD DATA FOLDER +for i in $(seq 0 $(($NODES - 1))); +do + # first validator is already setup + if [[ "$i" -ne 0 ]]; then + VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") + echo "$VALIDATORS" | jq -r ".[$i].mnemonic" | $BIN keys add validator$VAL_ID \ + --home /$CHAIN_ID/validator$VAL_ID \ + --keyring-backend test \ + --recover > /dev/null + + # Copy in the genesis.json + cp /sover/validatoralice/config/genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json + cp -r /sover/validatoralice/data /$CHAIN_ID/validator$VAL_ID/ + + # Copy in validator state file + # echo '{"height": "0","round": 0,"step": 0}' > /$CHAIN_ID/validator$VAL_ID/data/priv_validator_state.json + + + PRIV_VALIDATOR_KEY=$(echo "$VALIDATORS" | jq -r ".[$i].priv_validator_key") + if [[ "$PRIV_VALIDATOR_KEY" ]]; then + echo "$PRIV_VALIDATOR_KEY" > /$CHAIN_ID/validator$VAL_ID/config/priv_validator_key.json + fi + + NODE_KEY=$(echo "$VALIDATORS" | jq -r ".[$i].node_key") + if [[ "$NODE_KEY" ]]; then + echo "$NODE_KEY" > /$CHAIN_ID/validator$VAL_ID/config/node_key.json + fi + + # Modify tendermint configs of validator + if [ "$TENDERMINT_CONFIG_TRANSFORM" != "" ] ; then + #'s/foo/bar/;s/abc/def/' + sed -i "$TENDERMINT_CONFIG_TRANSFORM" $CHAIN_ID/validator$VAL_ID/config/config.toml + fi + fi +done + + +# START VALIDATOR NODES -> this will perform the sovereign upgrade and start the chain +# ALICE is a validator on the sovereign and also the validator on the consumer chain +# BOB, CAROL are not validators on the sovereign, they will become validator once the chain switches to the consumer chain +echo "Starting validator nodes..." +for i in $(seq 0 $(($NODES - 1))); +do + VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") + VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$i].ip_suffix") + NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" + + GAIA_HOME="--home /$CHAIN_ID/validator$VAL_ID" + RPC_ADDRESS="--rpc.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" + GRPC_ADDRESS="--grpc.address $CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:9091" + LISTEN_ADDRESS="--address tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655" + P2P_ADDRESS="--p2p.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26656" + # LOG_LEVEL="--log_level trace" # switch to trace to see panic messages and rich and all debug msgs + LOG_LEVEL="--log_level info" + ENABLE_WEBGRPC="--grpc-web.enable=false" + + PERSISTENT_PEERS="" + + for j in $(seq 0 $(($NODES - 1))); + do + if [ $i -ne $j ]; then + PEER_VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$j].val_id") + PEER_VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$j].ip_suffix") + NODE_ID=$($BIN tendermint show-node-id --home /$CHAIN_ID/validator$PEER_VAL_ID) + ADDRESS="$NODE_ID@$CHAIN_IP_PREFIX.$PEER_VAL_IP_SUFFIX:26656" + # (jq -r '.body.memo' /$CHAIN_ID/validator$j/config/gentx/*) # Getting the address from the gentx should also work + PERSISTENT_PEERS="$PERSISTENT_PEERS,$ADDRESS" + fi + done + + # Remove leading comma and concat to flag + PERSISTENT_PEERS="--p2p.persistent_peers ${PERSISTENT_PEERS:1}" + + ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC $PERSISTENT_PEERS" + ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & +done + +QUERY_NODE_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") +echo "NODE SUFFIX: $QUERY_NODE_SUFFIX" +# poll for chain start +set +e +until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_NODE_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done +set -e + +echo "done!!!!!!!!" + +read -p "Press Return to Close..." \ No newline at end of file diff --git a/tests/e2e/testnet-scripts/start-sovereign.sh b/tests/e2e/testnet-scripts/start-sovereign.sh new file mode 100644 index 0000000000..9daed9a207 --- /dev/null +++ b/tests/e2e/testnet-scripts/start-sovereign.sh @@ -0,0 +1,133 @@ +#!/bin/bash +set -eux + +# The gaiad binary +BIN=$1 + +# JSON array of validator information +# [{ +# mnemonic: "crackle snap pop ... etc", +# allocation: "10000000000stake,10000000000footoken", +# stake: "5000000000stake", +# val_id: "alice", +# ip_suffix: "1", +# priv_validator_key: "{\"address\": \"3566F464673B2F069758DAE86FC25D04017BB147\",\"pub_key\": {\"type\": \"tendermint/PubKeyEd25519\",\"value\": \"XrLjKdc4mB2gfqplvnoySjSJq2E90RynUwaO3WhJutk=\"},\"priv_key\": {\"type\": \"tendermint/PrivKeyEd25519\",\"value\": \"czGSLs/Ocau8aJ5J5zQHMxf3d7NR0xjMECN6YGTIWqtesuMp1ziYHaB+qmW+ejJKNImrYT3RHKdTBo7daEm62Q==\"}}" +# node_key: "{\"priv_key\":{\"type\":\"tendermint/PrivKeyEd25519\",\"value\":\"alIHj6hXnzpLAadgb7+E2eeecwxoNdzuZrfhMX36EaD5/LgzL0ZUoVp7AK3np0K5T35JWLLv0jJKmeRIhG0GjA==\"}}" +# }, ... ] +VALIDATORS=$2 + +# The chain ID +CHAIN_ID=$3 + +# This is the first 3 fields of the IP addresses which will be used internally by the validators of this blockchain +# Recommended to use something starting with 7, since it is squatted by the DoD and is unroutable on the internet +# For example: "7.7.7" +CHAIN_IP_PREFIX=$4 + +# A transformation to apply to the genesis file, as a jq string +GENESIS_TRANSFORM=$5 + +# A sed string modifying the tendermint config +TENDERMINT_CONFIG_TRANSFORM=$6 + +# SETUP NETWORK NAMESPACES, see: https://adil.medium.com/container-networking-under-the-hood-network-namespaces-6b2b8fe8dc2a + +# Create virtual bridge device (acts like a switch) +ip link add name virtual-bridge type bridge || true + +# used globally in the whole script +VAL_ID=$(echo "$VALIDATORS" | jq -r ".[0].val_id") +VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") +NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" +IP_ADDR="$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX/24" + +# Create network namespace +ip netns add $NET_NAMESPACE_NAME +# Create virtual ethernet device to connect with bridge +ip link add $NET_NAMESPACE_NAME-in type veth peer name $NET_NAMESPACE_NAME-out +# Connect input end of virtual ethernet device to namespace +ip link set $NET_NAMESPACE_NAME-in netns $NET_NAMESPACE_NAME +# Assign ip address to namespace +ip netns exec $NET_NAMESPACE_NAME ip addr add $IP_ADDR dev $NET_NAMESPACE_NAME-in +# Connect output end of virtual ethernet device to bridge +ip link set $NET_NAMESPACE_NAME-out master virtual-bridge + +# Enable bridge interface +ip link set virtual-bridge up + +NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" +# Enable in/out interfaces for the namespace +ip link set $NET_NAMESPACE_NAME-out up +ip netns exec $NET_NAMESPACE_NAME ip link set dev $NET_NAMESPACE_NAME-in up +# Enable loopback device +ip netns exec $NET_NAMESPACE_NAME ip link set dev lo up + +# Assign IP for bridge, to route between default network namespace and bridge +BRIDGE_IP="$CHAIN_IP_PREFIX.254/24" +ip addr add $BRIDGE_IP dev virtual-bridge + +# first we start a genesis.json with the first validator +# the first validator will also collect the gentx's once gnerated +echo "$VALIDATORS" | jq -r ".[0].mnemonic" | $BIN init --home /$CHAIN_ID/validator$VAL_ID --chain-id=$CHAIN_ID validator$VAL_ID --recover > /dev/null + +# !!!!!!!!! IMPORTANT !!!!!!!!! # +# move the sovereign genesis to the correct validator home dir +cp /testnet-scripts/sovereign-genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json + +# Apply jq transformations to genesis file +jq "$GENESIS_TRANSFORM" /$CHAIN_ID/validator$VAL_ID/config/genesis.json > /$CHAIN_ID/edited-genesis.json +mv /$CHAIN_ID/edited-genesis.json /$CHAIN_ID/genesis.json +cp /$CHAIN_ID/genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json + + + +# SETUP LOCAL VALIDATOR STATE +echo '{"height": "0","round": 0,"step": 0}' > /$CHAIN_ID/validator$VAL_ID/data/priv_validator_state.json + +PRIV_VALIDATOR_KEY=$(echo "$VALIDATORS" | jq -r ".[0].priv_validator_key") +if [[ "$PRIV_VALIDATOR_KEY" ]]; then + echo "$PRIV_VALIDATOR_KEY" > /$CHAIN_ID/validator$VAL_ID/config/priv_validator_key.json +fi + +NODE_KEY=$(echo "$VALIDATORS" | jq -r ".[0].node_key") +if [[ "$NODE_KEY" ]]; then + echo "$NODE_KEY" > /$CHAIN_ID/validator$VAL_ID/config/node_key.json +fi + +echo "$VALIDATORS" | jq -r ".[0].mnemonic" | $BIN keys add validator$VAL_ID \ +--home /$CHAIN_ID/validator$VAL_ID \ +--keyring-backend test \ +--recover > /dev/null + +# Modify tendermint configs of validator +if [ "$TENDERMINT_CONFIG_TRANSFORM" != "" ] ; then + #'s/foo/bar/;s/abc/def/' + sed -i "$TENDERMINT_CONFIG_TRANSFORM" $CHAIN_ID/validator$VAL_ID/config/config.toml +fi + + +# START VALIDATOR NODE +VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") +NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" + +GAIA_HOME="--home /$CHAIN_ID/validator$VAL_ID" +RPC_ADDRESS="--rpc.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" +GRPC_ADDRESS="--grpc.address $CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:9091" +LISTEN_ADDRESS="--address tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655" +P2P_ADDRESS="--p2p.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26656" +# LOG_LEVEL="--log_level trace" # switch to trace to see panic messages and rich and all debug msgs +LOG_LEVEL="--log_level info" +ENABLE_WEBGRPC="--grpc-web.enable=false" + +ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC" +ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & + + +# poll for chain start +set +e +until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done +set -e + +echo "done!!!!!!!!" + +read -p "Press Return to Close..." \ No newline at end of file diff --git a/tests/integration/changeover.go b/tests/integration/changeover.go index 876d8b5c16..bd94857598 100644 --- a/tests/integration/changeover.go +++ b/tests/integration/changeover.go @@ -34,7 +34,7 @@ func (suite *CCVTestSuite) TestRecycleTransferChannel() { // Setup state s.t. the consumer keeper emulates a consumer that was previously standalone consumerKeeper.MarkAsPrevStandaloneChain(suite.consumerCtx()) suite.Require().True(consumerKeeper.IsPrevStandaloneChain(suite.consumerCtx())) - suite.consumerApp.GetConsumerKeeper().SetStandaloneTransferChannelID(suite.consumerCtx(), resp.ChannelId) + suite.consumerApp.GetConsumerKeeper().SetDistributionTransmissionChannel(suite.consumerCtx(), resp.ChannelId) // Now finish setting up CCV channel suite.ExecuteCCVChannelHandshake(suite.path) diff --git a/tests/integration/common.go b/tests/integration/common.go index bd62e5785c..8f32193206 100644 --- a/tests/integration/common.go +++ b/tests/integration/common.go @@ -16,11 +16,11 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/testutil/integration" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" ) diff --git a/tests/integration/democracy.go b/tests/integration/democracy.go index 7587350209..c1262b31c1 100644 --- a/tests/integration/democracy.go +++ b/tests/integration/democracy.go @@ -6,15 +6,15 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - testutil "github.com/cosmos/interchain-security/testutil/integration" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" "github.com/stretchr/testify/suite" ) diff --git a/tests/integration/distribution.go b/tests/integration/distribution.go index a565d72ec3..58132fcc62 100644 --- a/tests/integration/distribution.go +++ b/tests/integration/distribution.go @@ -5,9 +5,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // This test is valid for minimal viable consumer chain @@ -20,6 +23,11 @@ func (s *CCVTestSuite) TestRewardsDistribution() { delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() + // register a consumer reward denom + params := s.consumerApp.GetConsumerKeeper().GetConsumerParams(s.consumerCtx()) + params.RewardDenoms = []string{sdk.DefaultBondDenom} + s.consumerApp.GetConsumerKeeper().SetParams(s.consumerCtx(), params) + // relay VSC packets from provider to consumer relayAllCommittedPackets(s, s.providerChain, s.path, ccv.ProviderPortID, s.path.EndpointB.ChannelID, 1) @@ -29,7 +37,9 @@ func (s *CCVTestSuite) TestRewardsDistribution() { s.consumerChain.NextBlock() consumerAccountKeeper := s.consumerApp.GetTestAccountKeeper() + providerAccountKeeper := s.providerApp.GetTestAccountKeeper() consumerBankKeeper := s.consumerApp.GetTestBankKeeper() + providerBankKeeper := s.providerApp.GetTestBankKeeper() // send coins to the fee pool which is used for reward distribution consumerFeePoolAddr := consumerAccountKeeper.GetModuleAccount(s.consumerCtx(), authtypes.FeeCollectorName).GetAddress() @@ -65,14 +75,68 @@ func (s *CCVTestSuite) TestRewardsDistribution() { relayAllCommittedPackets(s, s.consumerChain, s.transferPath, transfertypes.PortID, s.transferPath.EndpointA.ChannelID, 1) s.providerChain.NextBlock() - communityCoins := s.providerApp.GetTestDistributionKeeper().GetFeePoolCommunityCoins(s.providerCtx()) + + // Since consumer reward denom is not yet registered, the coins never get into the fee pool, staying in the ConsumerRewardsPool + rewardPool := providerAccountKeeper.GetModuleAccount(s.providerCtx(), providertypes.ConsumerRewardsPool).GetAddress() + rewardCoins := providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) + ibcCoinIndex := -1 - for i, coin := range communityCoins { + for i, coin := range rewardCoins { if strings.HasPrefix(coin.Denom, "ibc") { ibcCoinIndex = i } } + + // Check that we found an ibc denom in the reward pool s.Require().Greater(ibcCoinIndex, -1) + + // Check that the coins got into the ConsumerRewardsPool + s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) + + // Attempt to register the consumer reward denom, but fail because the account has no coins + + // Get the balance of delAddr to send it out + senderCoins := providerBankKeeper.GetAllBalances(s.providerCtx(), delAddr) + + // Send the coins to the governance module just to have a place to send them + err = providerBankKeeper.SendCoinsFromAccountToModule(s.providerCtx(), delAddr, govtypes.ModuleName, senderCoins) + s.Require().NoError(err) + + // Attempt to register the consumer reward denom, but fail because the account has no coins + err = s.providerApp.GetProviderKeeper().RegisterConsumerRewardDenom(s.providerCtx(), rewardCoins[ibcCoinIndex].Denom, delAddr) + s.Require().Error(err) + + // Advance a block and check that the coins are still in the ConsumerRewardsPool + s.providerChain.NextBlock() + rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) + s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) + + // Successfully register the consumer reward denom this time + + // Send the coins back to the delAddr + err = providerBankKeeper.SendCoinsFromModuleToAccount(s.providerCtx(), govtypes.ModuleName, delAddr, senderCoins) + s.Require().NoError(err) + + // log the sender's coins + senderCoins1 := providerBankKeeper.GetAllBalances(s.providerCtx(), delAddr) + + // Register the consumer reward denom + err = s.providerApp.GetProviderKeeper().RegisterConsumerRewardDenom(s.providerCtx(), rewardCoins[ibcCoinIndex].Denom, delAddr) + s.Require().NoError(err) + + // Check that the delAddr has the right amount less money in it after paying the fee + senderCoins2 := providerBankKeeper.GetAllBalances(s.providerCtx(), delAddr) + consumerRewardDenomRegistrationFee := s.providerApp.GetProviderKeeper().GetConsumerRewardDenomRegistrationFee(s.providerCtx()) + s.Require().Equal(senderCoins1.Sub(senderCoins2...), sdk.NewCoins(consumerRewardDenomRegistrationFee)) + + s.providerChain.NextBlock() + + // Check that the reward pool has no more coins because they were transferred to the fee pool + rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) + s.Require().Equal(0, len(rewardCoins)) + + // check that the fee pool has the expected amount of coins + communityCoins := s.providerApp.GetTestDistributionKeeper().GetFeePoolCommunityCoins(s.providerCtx()) s.Require().True(communityCoins[ibcCoinIndex].Amount.Equal(sdk.NewDecCoinFromCoin(providerExpectedRewards[0]).Amount)) } @@ -88,6 +152,11 @@ func (s *CCVTestSuite) TestSendRewardsRetries() { delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() + // Register denom on consumer chain + params := s.consumerApp.GetConsumerKeeper().GetConsumerParams(s.consumerCtx()) + params.RewardDenoms = []string{sdk.DefaultBondDenom} + s.consumerApp.GetConsumerKeeper().SetParams(s.consumerCtx(), params) + // relay VSC packets from provider to consumer relayAllCommittedPackets(s, s.providerChain, s.path, ccv.ProviderPortID, s.path.EndpointB.ChannelID, 1) @@ -156,12 +225,14 @@ func (s *CCVTestSuite) TestEndBlockRD() { corruptTransChannel bool expLBThUpdated bool expEscrowBalanceChanged bool + denomRegistered bool }{ { name: "should not update LBTH before blocks per dist trans block are passed", prepareRewardDist: false, corruptTransChannel: false, expLBThUpdated: false, + denomRegistered: true, expEscrowBalanceChanged: false, }, { @@ -169,6 +240,7 @@ func (s *CCVTestSuite) TestEndBlockRD() { prepareRewardDist: true, corruptTransChannel: false, expLBThUpdated: true, + denomRegistered: true, expEscrowBalanceChanged: true, }, { @@ -176,8 +248,25 @@ func (s *CCVTestSuite) TestEndBlockRD() { prepareRewardDist: true, corruptTransChannel: true, expLBThUpdated: true, + denomRegistered: true, + expEscrowBalanceChanged: false, + }, + { + name: "should not change escrow balance when denom is not registered", + prepareRewardDist: true, + corruptTransChannel: false, + expLBThUpdated: true, + denomRegistered: false, expEscrowBalanceChanged: false, }, + { + name: "should change escrow balance when denom is registered", + prepareRewardDist: true, + corruptTransChannel: false, + expLBThUpdated: true, + denomRegistered: true, + expEscrowBalanceChanged: true, + }, } for _, tc := range testCases { @@ -192,6 +281,12 @@ func (s *CCVTestSuite) TestEndBlockRD() { delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() + if tc.denomRegistered { + params := s.consumerApp.GetConsumerKeeper().GetConsumerParams(s.consumerCtx()) + params.RewardDenoms = []string{sdk.DefaultBondDenom} + s.consumerApp.GetConsumerKeeper().SetParams(s.consumerCtx(), params) + } + // relay VSC packets from provider to consumer relayAllCommittedPackets(s, s.providerChain, s.path, ccv.ProviderPortID, s.path.EndpointB.ChannelID, 1) diff --git a/tests/integration/expired_client.go b/tests/integration/expired_client.go index 1963f293c4..ae7570a57f 100644 --- a/tests/integration/expired_client.go +++ b/tests/integration/expired_client.go @@ -10,8 +10,9 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // TestVSCPacketSendWithExpiredClient tests queueing of VSCPackets when the consumer client is expired. diff --git a/tests/integration/instance_test.go b/tests/integration/instance_test.go index cd6ddcfe35..7e1e8dd608 100644 --- a/tests/integration/instance_test.go +++ b/tests/integration/instance_test.go @@ -3,11 +3,11 @@ package integration_test import ( "testing" - appConsumer "github.com/cosmos/interchain-security/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/app/provider" - intg "github.com/cosmos/interchain-security/tests/integration" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v2/app/provider" + intg "github.com/cosmos/interchain-security/v2/tests/integration" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" "github.com/stretchr/testify/suite" ) diff --git a/tests/integration/key_assignment.go b/tests/integration/key_assignment.go index abb64c04a0..e6a794fedf 100644 --- a/tests/integration/key_assignment.go +++ b/tests/integration/key_assignment.go @@ -6,8 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/ibc-go/v7/testing/mock" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) func (s *CCVTestSuite) TestKeyAssignment() { diff --git a/tests/integration/normal_operations.go b/tests/integration/normal_operations.go index 31514090a8..3318e29940 100644 --- a/tests/integration/normal_operations.go +++ b/tests/integration/normal_operations.go @@ -3,7 +3,7 @@ package integration import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // Tests the tracking of historical info in the context of new blocks being committed diff --git a/tests/integration/setup.go b/tests/integration/setup.go index ce597efb36..86084545c6 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -7,15 +7,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" "github.com/cosmos/ibc-go/v7/testing/mock" - testutil "github.com/cosmos/interchain-security/testutil/integration" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" "github.com/stretchr/testify/suite" ) diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index b6ec62f75f..8b4cb80547 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -4,21 +4,20 @@ import ( "fmt" "time" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/ed25519" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" tmtypes "github.com/cometbft/cometbft/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - keepertestutil "github.com/cosmos/interchain-security/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - - abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/crypto/ed25519" + keepertestutil "github.com/cosmos/interchain-security/v2/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) // TestRelayAndApplyDowntimePacket tests that downtime slash packets can be properly relayed diff --git a/tests/integration/stop_consumer.go b/tests/integration/stop_consumer.go index 8c506a1819..fda0aeb441 100644 --- a/tests/integration/stop_consumer.go +++ b/tests/integration/stop_consumer.go @@ -5,8 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // Tests the functionality of stopping a consumer chain at a higher level than unit tests @@ -83,7 +84,7 @@ func (s *CCVTestSuite) TestStopConsumerChain() { func(suite *CCVTestSuite) error { // Queue slash and vsc packet data for consumer 0, these queue entries will be removed firstBundle := s.getFirstBundle() - globalEntry := types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), firstBundle.Chain.ChainID, 7, types.ProviderConsAddress{}) + globalEntry := types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), firstBundle.Chain.ChainID, 7, types.ProviderConsAddress{Address: []byte{}}) providerKeeper.QueueGlobalSlashEntry(s.providerCtx(), globalEntry) err := providerKeeper.QueueThrottledSlashPacketData(s.providerCtx(), firstBundle.Chain.ChainID, 1, ccv.SlashPacketData{ValsetUpdateId: 1}) @@ -94,7 +95,7 @@ func (s *CCVTestSuite) TestStopConsumerChain() { // Queue slash and vsc packet data for consumer 1, these queue entries will be not be removed secondBundle := s.getBundleByIdx(1) - globalEntry = types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), secondBundle.Chain.ChainID, 7, types.ProviderConsAddress{}) + globalEntry = types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), secondBundle.Chain.ChainID, 7, types.ProviderConsAddress{Address: []byte{}}) providerKeeper.QueueGlobalSlashEntry(s.providerCtx(), globalEntry) err = providerKeeper.QueueThrottledSlashPacketData(s.providerCtx(), secondBundle.Chain.ChainID, 1, ccv.SlashPacketData{ValsetUpdateId: 1}) diff --git a/tests/integration/throttle.go b/tests/integration/throttle.go index 693fc064b6..289c57e9d0 100644 --- a/tests/integration/throttle.go +++ b/tests/integration/throttle.go @@ -7,11 +7,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) +const fullSlashMeterString = "1.0" + // TestBasicSlashPacketThrottling tests slash packet throttling with a single consumer, // two slash packets, and no VSC matured packets. The most basic scenario. func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { @@ -651,7 +654,7 @@ func (s *CCVTestSuite) TestSlashSameValidator() { // Set replenish fraction to 1.0 so that all sent packets should handled immediately (no throttling) params := providerKeeper.GetParams(s.providerCtx()) - params.SlashMeterReplenishFraction = "1.0" + params.SlashMeterReplenishFraction = fullSlashMeterString // needs to be const for linter providerKeeper.SetParams(s.providerCtx(), params) providerKeeper.InitializeSlashMeter(s.providerCtx()) @@ -706,7 +709,7 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes // Set replenish fraction to 1.0 so that all sent packets should be handled immediately (no throttling) params := providerKeeper.GetParams(s.providerCtx()) - params.SlashMeterReplenishFraction = "1.0" + params.SlashMeterReplenishFraction = fullSlashMeterString // needs to be const for linter providerKeeper.SetParams(s.providerCtx(), params) providerKeeper.InitializeSlashMeter(s.providerCtx()) @@ -779,7 +782,7 @@ func (s *CCVTestSuite) TestLeadingVSCMaturedAreDequeued() { // Queue up 50 slash packets for each consumer for _, bundle := range s.consumerBundles { - for i := 0; i < 50; i++ { + for i := 50; i < 100; i++ { ibcSeqNum := uint64(i) packet := s.constructSlashPacketFromConsumer(*bundle, *s.providerChain.Vals.Validators[0], stakingtypes.Infraction_INFRACTION_DOWNTIME, ibcSeqNum) @@ -792,7 +795,7 @@ func (s *CCVTestSuite) TestLeadingVSCMaturedAreDequeued() { // Queue up another 50 vsc matured packets for each consumer for _, bundle := range s.consumerBundles { - for i := 0; i < 50; i++ { + for i := 100; i < 150; i++ { ibcSeqNum := uint64(i) packet := s.constructVSCMaturedPacketFromConsumer(*bundle, ibcSeqNum) packetData := ccvtypes.ConsumerPacketData{} @@ -818,6 +821,10 @@ func (s *CCVTestSuite) TestLeadingVSCMaturedAreDequeued() { providerKeeper.SetSlashMeterReplenishTimeCandidate(s.providerCtx()) // Execute end blocker to dequeue only the leading vsc matured packets. + // Note we must call the end blocker three times, since only 100 vsc matured packets can be handled + // each block, and we have 5*50=250 total. + s.providerChain.NextBlock() + s.providerChain.NextBlock() s.providerChain.NextBlock() // Confirm queue size is 100 for each consumer-specific queue (50 leading vsc matured are dequeued). @@ -827,7 +834,78 @@ func (s *CCVTestSuite) TestLeadingVSCMaturedAreDequeued() { } // No slash packets handled, global slash queue is same size as last block. + globalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) + s.Require().Equal(len(globalEntries), 50*5) + + // No slash packets handled even if we call end blocker a couple more times. + s.providerChain.NextBlock() + s.providerChain.NextBlock() + globalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) + s.Require().Equal(len(globalEntries), 50*5) +} + +// TestVscMaturedHandledPerBlockLimit tests that only 100 vsc matured packets are handled per block, +// specifically from HandleThrottleQueues(). +// +// Note the vsc matured per block limit is also tested in, TestLeadingVSCMaturedAreDequeued, +// specifically in the context of HandleLeadingVSCMaturedPackets(). +func (s *CCVTestSuite) TestVscMaturedHandledPerBlockLimit() { + s.SetupAllCCVChannels() + providerKeeper := s.providerApp.GetProviderKeeper() + + // Set replenish fraction to 1.0 so that all sent packets should be handled immediately (no jail throttling) + params := providerKeeper.GetParams(s.providerCtx()) + params.SlashMeterReplenishFraction = fullSlashMeterString // needs to be const for linter + providerKeeper.SetParams(s.providerCtx(), params) + providerKeeper.InitializeSlashMeter(s.providerCtx()) + + // Queue up 100 vsc matured packets for each consumer + for _, bundle := range s.consumerBundles { + for i := 0; i < 100; i++ { + ibcSeqNum := uint64(i) + packet := s.constructVSCMaturedPacketFromConsumer(*bundle, ibcSeqNum) + packetData := ccvtypes.ConsumerPacketData{} + ccvtypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &packetData) + providerKeeper.OnRecvVSCMaturedPacket(s.providerCtx(), + packet, *packetData.GetVscMaturedPacketData()) + } + } + + // Queue up 50 slash packets for each consumer, with new IBC sequence numbers + for _, bundle := range s.consumerBundles { + for i := 100; i < 150; i++ { + ibcSeqNum := uint64(i) + packet := s.constructSlashPacketFromConsumer(*bundle, + *s.providerChain.Vals.Validators[0], stakingtypes.Infraction_INFRACTION_DOWNTIME, ibcSeqNum) + packetData := ccvtypes.ConsumerPacketData{} + ccvtypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &packetData) + providerKeeper.OnRecvSlashPacket(s.providerCtx(), + packet, *packetData.GetSlashPacketData()) + } + } + + // Confirm queue size is 150 for each consumer-specific queue. + for _, bundle := range s.consumerBundles { + s.Require().Equal(uint64(150), + providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), bundle.Chain.ChainID)) + } + // Confirm global queue size is 50 * 5 (50 slash packets for each of 5 consumers) + globalEntries := providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) s.Require().Equal(len(globalEntries), 50*5) + + // Note even though there is no jail throttling active, slash packets will not be handled until + // all of the leading vsc matured packets are handled first. This should take 5 blocks. + for i := 0; i < 5; i++ { + s.providerChain.NextBlock() + s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 250) // global entries remain same size + } + + // Set signing info for val to be jailed, preventing panic + s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[0]) + + // Now we execute one more block and all 250 of the slash packets should be handled. + s.providerChain.NextBlock() + s.Require().Empty(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx())) // empty global entries = all slash packets handled } func (s *CCVTestSuite) confirmValidatorJailed(tmVal tmtypes.Validator, checkPower bool) { diff --git a/tests/integration/unbonding.go b/tests/integration/unbonding.go index d88f4c78c3..6b14099d45 100644 --- a/tests/integration/unbonding.go +++ b/tests/integration/unbonding.go @@ -6,8 +6,8 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // TestUndelegationNormalOperation tests that undelegations complete after diff --git a/tests/integration/valset_update.go b/tests/integration/valset_update.go index b3a36ea55b..6e231976c4 100644 --- a/tests/integration/valset_update.go +++ b/tests/integration/valset_update.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // TestPacketRoundtrip tests a CCV packet roundtrip when tokens are bonded on provider diff --git a/testutil/crypto/crypto.go b/testutil/crypto/crypto.go index 1a25329fda..1becc4248e 100644 --- a/testutil/crypto/crypto.go +++ b/testutil/crypto/crypto.go @@ -11,7 +11,7 @@ import ( sdkcryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdktypes "github.com/cosmos/cosmos-sdk/types" sdkstakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" tmcrypto "github.com/cometbft/cometbft/crypto" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index 66f2098f6f..67e169af98 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -6,10 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - testutil "github.com/cosmos/interchain-security/testutil/integration" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + testutil "github.com/cosmos/interchain-security/v2/testutil/integration" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" "github.com/stretchr/testify/suite" diff --git a/testutil/ibc_testing/specific_setup.go b/testutil/ibc_testing/specific_setup.go index 5a85c108e3..ab9715ebd9 100644 --- a/testutil/ibc_testing/specific_setup.go +++ b/testutil/ibc_testing/specific_setup.go @@ -8,14 +8,14 @@ import ( "encoding/json" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" tmdb "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" - appConsumer "github.com/cosmos/interchain-security/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/app/provider" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v2/app/provider" ) // ProviderAppIniter implements ibctesting.AppIniter for a provider app diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 8549d12217..b6456663a9 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -6,11 +6,11 @@ import ( "reflect" "testing" - appConsumer "github.com/cosmos/interchain-security/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/app/provider" - integr "github.com/cosmos/interchain-security/tests/integration" - icstestingutils "github.com/cosmos/interchain-security/testutil/ibc_testing" + appConsumer "github.com/cosmos/interchain-security/v2/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v2/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v2/app/provider" + integr "github.com/cosmos/interchain-security/v2/tests/integration" + icstestingutils "github.com/cosmos/interchain-security/v2/testutil/ibc_testing" ) // runCCVTestByName runs a single CCV integration test by name, using a CCVTestSuite @@ -205,6 +205,10 @@ func TestLeadingVSCMaturedAreDequeued(t *testing.T) { runCCVTestByName(t, "TestLeadingVSCMaturedAreDequeued") } +func TestVscMaturedHandledPerBlockLimit(t *testing.T) { + runCCVTestByName(t, "TestVscMaturedHandledPerBlockLimit") +} + // // Unbonding tests // diff --git a/testutil/integration/interfaces.go b/testutil/integration/interfaces.go index f4e366db50..6fe667c2fa 100644 --- a/testutil/integration/interfaces.go +++ b/testutil/integration/interfaces.go @@ -15,16 +15,18 @@ import ( paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // The interface that any provider app must implement to be compatible with ccv integration tests. // This is a wrapper around the ibc testing app interface with additional constraints. type ProviderApp interface { ibctesting.TestingApp + GetSubspace(moduleName string) paramstypes.Subspace // // Keeper getters @@ -33,12 +35,14 @@ type ProviderApp interface { GetProviderKeeper() providerkeeper.Keeper // Returns a staking keeper interface with more capabilities than the expected_keepers interface GetTestStakingKeeper() TestStakingKeeper - // Testurns a bank keeper interface with more capabilities than the expected_keepers interface + // Returns a bank keeper interface with more capabilities than the expected_keepers interface GetTestBankKeeper() TestBankKeeper - // Testurns a slashing keeper interface with more capabilities than the expected_keepers interface + // Returns a slashing keeper interface with more capabilities than the expected_keepers interface GetTestSlashingKeeper() TestSlashingKeeper - // Integrurns a distribution keeper interface with more capabilities than the expected_keepers interface + // Returns a distribution keeper interface with more capabilities than the expected_keepers interface GetTestDistributionKeeper() TestDistributionKeeper + // Returns an account keeper interface with more capabilities than the expected_keepers interface + GetTestAccountKeeper() TestAccountKeeper } // The interface that any consumer app must implement to be compatible with integration tests @@ -105,6 +109,8 @@ type TestBankKeeper interface { ccvtypes.BankKeeper SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, + recipientAddr sdk.AccAddress, amt sdk.Coins) error } type TestAccountKeeper interface { diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go index cc2dbdc149..06b5008750 100644 --- a/testutil/keeper/expectations.go +++ b/testutil/keeper/expectations.go @@ -6,15 +6,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/golang/mock/gomock" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - "github.com/golang/mock/gomock" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" extra "github.com/oxyno-zeta/gomock-extra-matcher" ) diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks.go index c8b6897958..fea83079d3 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks.go @@ -48,6 +48,20 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder { return m.recorder } +// BondDenom mocks base method. +func (m *MockStakingKeeper) BondDenom(ctx types0.Context) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BondDenom", ctx) + ret0, _ := ret[0].(string) + return ret0 +} + +// BondDenom indicates an expected call of BondDenom. +func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondDenom", reflect.TypeOf((*MockStakingKeeper)(nil).BondDenom), ctx) +} + // Delegation mocks base method. func (m *MockStakingKeeper) Delegation(ctx types0.Context, addr types0.AccAddress, valAddr types0.ValAddress) types5.DelegationI { m.ctrl.T.Helper() @@ -98,6 +112,13 @@ func (m *MockStakingKeeper) GetLastValidators(ctx types0.Context) []types5.Valid return ret0 } +// GetLastValidators indicates an expected call of GetLastValidators. +func (mr *MockStakingKeeperMockRecorder) GetLastValidators(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastValidators", reflect.TypeOf((*MockStakingKeeper)(nil).GetLastValidators), ctx) +} + +// GetUnbondingType mocks base method. func (m *MockStakingKeeper) GetUnbondingType(ctx types0.Context, id uint64) (types5.UnbondingType, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnbondingType", ctx, id) @@ -106,10 +127,10 @@ func (m *MockStakingKeeper) GetUnbondingType(ctx types0.Context, id uint64) (typ return ret0, ret1 } -// GetLastValidators indicates an expected call of GetLastValidators. -func (mr *MockStakingKeeperMockRecorder) GetLastValidators(ctx interface{}) *gomock.Call { +// GetUnbondingType indicates an expected call of GetUnbondingType. +func (mr *MockStakingKeeperMockRecorder) GetUnbondingType(ctx, id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastValidators", reflect.TypeOf((*MockStakingKeeper)(nil).GetLastValidators), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnbondingType", reflect.TypeOf((*MockStakingKeeper)(nil).GetUnbondingType), ctx, id) } // GetValidator mocks base method. @@ -751,6 +772,43 @@ func (mr *MockClientKeeperMockRecorder) GetSelfConsensusState(ctx, height interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSelfConsensusState", reflect.TypeOf((*MockClientKeeper)(nil).GetSelfConsensusState), ctx, height) } +// MockDistributionKeeper is a mock of DistributionKeeper interface. +type MockDistributionKeeper struct { + ctrl *gomock.Controller + recorder *MockDistributionKeeperMockRecorder +} + +// MockDistributionKeeperMockRecorder is the mock recorder for MockDistributionKeeper. +type MockDistributionKeeperMockRecorder struct { + mock *MockDistributionKeeper +} + +// NewMockDistributionKeeper creates a new mock instance. +func NewMockDistributionKeeper(ctrl *gomock.Controller) *MockDistributionKeeper { + mock := &MockDistributionKeeper{ctrl: ctrl} + mock.recorder = &MockDistributionKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { + return m.recorder +} + +// FundCommunityPool mocks base method. +func (m *MockDistributionKeeper) FundCommunityPool(ctx types0.Context, amount types0.Coins, sender types0.AccAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) + ret0, _ := ret[0].(error) + return ret0 +} + +// FundCommunityPool indicates an expected call of FundCommunityPool. +func (mr *MockDistributionKeeperMockRecorder) FundCommunityPool(ctx, amount, sender interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FundCommunityPool", reflect.TypeOf((*MockDistributionKeeper)(nil).FundCommunityPool), ctx, amount, sender) +} + // MockConsumerHooks is a mock of ConsumerHooks interface. type MockConsumerHooks struct { ctrl *gomock.Controller diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index ab9a67d83a..d13ab17a63 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -19,11 +19,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - "github.com/cosmos/interchain-security/x/ccv/types" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -88,23 +88,25 @@ type MockedKeepers struct { *MockIBCTransferKeeper *MockIBCCoreKeeper *MockEvidenceKeeper + *MockDistributionKeeper } // NewMockedKeepers instantiates a struct with pointers to properly instantiated mocked keepers. func NewMockedKeepers(ctrl *gomock.Controller) MockedKeepers { return MockedKeepers{ - MockScopedKeeper: NewMockScopedKeeper(ctrl), - MockChannelKeeper: NewMockChannelKeeper(ctrl), - MockPortKeeper: NewMockPortKeeper(ctrl), - MockConnectionKeeper: NewMockConnectionKeeper(ctrl), - MockClientKeeper: NewMockClientKeeper(ctrl), - MockStakingKeeper: NewMockStakingKeeper(ctrl), - MockSlashingKeeper: NewMockSlashingKeeper(ctrl), - MockAccountKeeper: NewMockAccountKeeper(ctrl), - MockBankKeeper: NewMockBankKeeper(ctrl), - MockIBCTransferKeeper: NewMockIBCTransferKeeper(ctrl), - MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl), - MockEvidenceKeeper: NewMockEvidenceKeeper(ctrl), + MockScopedKeeper: NewMockScopedKeeper(ctrl), + MockChannelKeeper: NewMockChannelKeeper(ctrl), + MockPortKeeper: NewMockPortKeeper(ctrl), + MockConnectionKeeper: NewMockConnectionKeeper(ctrl), + MockClientKeeper: NewMockClientKeeper(ctrl), + MockStakingKeeper: NewMockStakingKeeper(ctrl), + MockSlashingKeeper: NewMockSlashingKeeper(ctrl), + MockAccountKeeper: NewMockAccountKeeper(ctrl), + MockBankKeeper: NewMockBankKeeper(ctrl), + MockIBCTransferKeeper: NewMockIBCTransferKeeper(ctrl), + MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl), + MockEvidenceKeeper: NewMockEvidenceKeeper(ctrl), + MockDistributionKeeper: NewMockDistributionKeeper(ctrl), } } @@ -123,6 +125,8 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi mocks.MockSlashingKeeper, mocks.MockAccountKeeper, mocks.MockEvidenceKeeper, + mocks.MockDistributionKeeper, + mocks.MockBankKeeper, authtypes.FeeCollectorName, ) } @@ -233,6 +237,7 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { time.Now(), consumertypes.DefaultConsumerRedistributeFrac, consumertypes.DefaultBlocksPerDistributionTransmission, + "", consumertypes.DefaultHistoricalEntries, types.DefaultCCVTimeoutPeriod, consumertypes.DefaultTransferTimeoutPeriod, diff --git a/testutil/simibc/chain_util.go b/testutil/simibc/chain_util.go index 0c3f9aff52..50015834e3 100644 --- a/testutil/simibc/chain_util.go +++ b/testutil/simibc/chain_util.go @@ -7,8 +7,8 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctestingcore "github.com/cosmos/interchain-security/legacy_ibc_testing/core" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctestingcore "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/core" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" ) // BeginBlock updates the current header and calls the app.BeginBlock method. diff --git a/testutil/simibc/relay_util.go b/testutil/simibc/relay_util.go index b3ac7bcd93..48e127aa60 100644 --- a/testutil/simibc/relay_util.go +++ b/testutil/simibc/relay_util.go @@ -1,15 +1,15 @@ package simibc import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - simapp "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + simapp "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" "github.com/stretchr/testify/require" ) @@ -160,7 +160,7 @@ func augmentHeader(sender *ibctesting.TestChain, receiver *ibctesting.TestChain, // NextValidatorsHash tmTrustedVals, ok = sender.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1)) if !ok { - return sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) + return errorsmod.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) } } trustedVals, err := tmTrustedVals.ToProto() diff --git a/testutil/simibc/relayed_path.go b/testutil/simibc/relayed_path.go index 82be53f68a..b5339b2923 100644 --- a/testutil/simibc/relayed_path.go +++ b/testutil/simibc/relayed_path.go @@ -5,7 +5,7 @@ import ( "time" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/interchain-security/legacy_ibc_testing/testing" + ibctesting "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/testing" ) // RelayedPath is a wrapper around ibctesting.Path gives fine-grained diff --git a/x/ccv/consumer/client/cli/query.go b/x/ccv/consumer/client/cli/query.go index 27910ef76b..3c42a8a33c 100644 --- a/x/ccv/consumer/client/cli/query.go +++ b/x/ccv/consumer/client/cli/query.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // NewQueryCmd returns a root CLI command handler for all x/ccv/provider query commands. diff --git a/x/ccv/consumer/ibc_module.go b/x/ccv/consumer/ibc_module.go index c662674a8b..410ca0d0fa 100644 --- a/x/ccv/consumer/ibc_module.go +++ b/x/ccv/consumer/ibc_module.go @@ -4,20 +4,22 @@ import ( "fmt" "strings" - sdkerrors "cosmossdk.io/errors" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // OnChanOpenInit implements the IBCModule interface @@ -40,7 +42,7 @@ func (am AppModule) OnChanOpenInit( // ensure provider channel hasn't already been created if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok { - return "", sdkerrors.Wrapf(types.ErrDuplicateChannel, + return "", errorsmod.Wrapf(types.ErrDuplicateChannel, "provider channel: %s already set", providerChannel) } @@ -53,7 +55,7 @@ func (am AppModule) OnChanOpenInit( // ensure the counterparty port ID matches the expected provider port ID if counterparty.PortId != types.ProviderPortID { - return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, + return "", errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty port: %s, expected %s", counterparty.PortId, types.ProviderPortID) } @@ -81,18 +83,18 @@ func validateCCVChannelParams( ) error { // Only ordered channels allowed if order != channeltypes.ORDERED { - return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) + return errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) } // the port ID must match the port ID the CCV module is bounded to boundPort := keeper.GetPort(ctx) if boundPort != portID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) + return errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) } // the version must match the expected version if version != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) + return errorsmod.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) } return nil } @@ -108,7 +110,7 @@ func (am AppModule) OnChanOpenTry( counterparty channeltypes.Counterparty, counterpartyVersion string, ) (string, error) { - return "", sdkerrors.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") + return "", errorsmod.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") } // OnChanOpenAck implements the IBCModule interface @@ -121,18 +123,18 @@ func (am AppModule) OnChanOpenAck( ) error { // ensure provider channel has not already been created if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok { - return sdkerrors.Wrapf(types.ErrDuplicateChannel, + return errorsmod.Wrapf(types.ErrDuplicateChannel, "provider channel: %s already established", providerChannel) } var md providertypes.HandshakeMetadata if err := (&md).Unmarshal([]byte(counterpartyMetadata)); err != nil { - return sdkerrors.Wrapf(types.ErrInvalidHandshakeMetadata, + return errorsmod.Wrapf(types.ErrInvalidHandshakeMetadata, "error unmarshalling ibc-ack metadata: \n%v; \nmetadata: %v", err, counterpartyMetadata) } if md.Version != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, + return errorsmod.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", md.Version, types.Version) } @@ -141,15 +143,10 @@ func (am AppModule) OnChanOpenAck( /////////////////////////////////////////////////// // Initialize distribution token transfer channel - // First check if an existing transfer channel exists, if this consumer was a previously standalone chain. - if am.keeper.IsPrevStandaloneChain(ctx) { - transChannelID := am.keeper.GetStandaloneTransferChannelID(ctx) - found := am.keeper.TransferChannelExists(ctx, transChannelID) - if found { - // If existing transfer channel is found, persist that channel ID and return - am.keeper.SetDistributionTransmissionChannel(ctx, transChannelID) - return nil - } + // First check if an existing transfer channel already exists. + transChannelID := am.keeper.GetDistributionTransmissionChannel(ctx) + if found := am.keeper.TransferChannelExists(ctx, transChannelID); found { + return nil } // NOTE The handshake for this channel is handled by the ibc-go/transfer @@ -196,7 +193,7 @@ func (am AppModule) OnChanOpenConfirm( portID, channelID string, ) error { - return sdkerrors.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") + return errorsmod.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") } // OnChanCloseInit implements the IBCModule interface @@ -209,7 +206,7 @@ func (am AppModule) OnChanCloseInit( if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok && providerChannel != channelID { return nil } - return sdkerrors.Wrap(sdkerrorstypes.ErrInvalidRequest, "user cannot close channel") + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") } // OnChanCloseConfirm implements the IBCModule interface @@ -260,7 +257,7 @@ func (am AppModule) OnAcknowledgementPacket( ) error { var ack channeltypes.Acknowledgement if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return sdkerrors.Wrapf(sdkerrorstypes.ErrUnknownRequest, "cannot unmarshal consumer packet acknowledgement: %v", err) + return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal consumer packet acknowledgement: %v", err) } if err := am.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { diff --git a/x/ccv/consumer/ibc_module_test.go b/x/ccv/consumer/ibc_module_test.go index 59e8815f47..18bbba83cf 100644 --- a/x/ccv/consumer/ibc_module_test.go +++ b/x/ccv/consumer/ibc_module_test.go @@ -9,11 +9,12 @@ import ( conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -121,9 +122,10 @@ func TestOnChanOpenInit(t *testing.T) { for _, tc := range testCases { // Common setup + keeperParams := testkeeper.NewInMemKeeperParams(t) consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) - consumerModule := consumer.NewAppModule(consumerKeeper) + t, keeperParams) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) consumerKeeper.SetPort(ctx, ccv.ConsumerPortID) consumerKeeper.SetProviderClientID(ctx, "clientIDToProvider") @@ -172,10 +174,11 @@ func TestOnChanOpenInit(t *testing.T) { // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-ccf-cotry1 // Spec tag: [CCV-CCF-COTRY.1] func TestOnChanOpenTry(t *testing.T) { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + keeperParams := testkeeper.NewInMemKeeperParams(t) + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) // No external keeper methods should be called defer ctrl.Finish() - consumerModule := consumer.NewAppModule(consumerKeeper) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) // OnOpenTry must error even with correct arguments _, err := consumerModule.OnChanOpenTry( @@ -212,7 +215,7 @@ func TestOnChanOpenAck(t *testing.T) { expPass bool }{ { - "success", + "success - empty transferChannelID", func(keeper *consumerkeeper.Keeper, params *params, mocks testkeeper.MockedKeepers) { // Expected msg distrTransferMsg := channeltypes.NewMsgChannelOpenInit( @@ -224,8 +227,13 @@ func TestOnChanOpenAck(t *testing.T) { "", // signer unused ) + transferChannelID := "" + keeper.SetDistributionTransmissionChannel(params.ctx, transferChannelID) + // Expected mock calls gomock.InOrder( + mocks.MockChannelKeeper.EXPECT().GetChannel( + params.ctx, transfertypes.PortID, transferChannelID).Return(channeltypes.Channel{}, false).Times(1), mocks.MockChannelKeeper.EXPECT().GetChannel( params.ctx, params.portID, params.channelID).Return(channeltypes.Channel{ ConnectionHops: []string{"connectionID"}, @@ -266,9 +274,10 @@ func TestOnChanOpenAck(t *testing.T) { for _, tc := range testCases { // Common setup + keeperParams := testkeeper.NewInMemKeeperParams(t) consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) - consumerModule := consumer.NewAppModule(consumerKeeper) + t, keeperParams) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) // Instantiate valid params as default. Individual test cases mutate these as needed. params := params{ @@ -316,9 +325,10 @@ func TestOnChanOpenAck(t *testing.T) { // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-ccf-coconfirm1 // Spec tag: [CCV-CCF-COCONFIRM.1] func TestOnChanOpenConfirm(t *testing.T) { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + keeperParams := testkeeper.NewInMemKeeperParams(t) + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) defer ctrl.Finish() - consumerModule := consumer.NewAppModule(consumerKeeper) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) err := consumerModule.OnChanOpenConfirm(ctx, ccv.ConsumerPortID, "channel-1") require.Error(t, err, "OnChanOpenConfirm callback must error on consumer chain") @@ -356,8 +366,9 @@ func TestOnChanCloseInit(t *testing.T) { } for _, tc := range testCases { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - consumerModule := consumer.NewAppModule(consumerKeeper) + keeperParams := testkeeper.NewInMemKeeperParams(t) + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) if tc.establishedProviderExists { consumerKeeper.SetProviderChannel(ctx, "provider") @@ -379,12 +390,13 @@ func TestOnChanCloseInit(t *testing.T) { // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-ccconfirm1// Spec tag: [CCV-CCF-CCINIT.1] // Spec tag: [CCV-PCF-CCCONFIRM.1] func TestOnChanCloseConfirm(t *testing.T) { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + keeperParams := testkeeper.NewInMemKeeperParams(t) + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) // No external keeper methods should be called defer ctrl.Finish() - consumerModule := consumer.NewAppModule(consumerKeeper) + consumerModule := consumer.NewAppModule(consumerKeeper, *keeperParams.ParamsSubspace) // Nothing happens, no error returned err := consumerModule.OnChanCloseConfirm(ctx, "portID", "channelID") diff --git a/x/ccv/consumer/keeper/changeover.go b/x/ccv/consumer/keeper/changeover.go index e3f1055cdf..1221792d3c 100644 --- a/x/ccv/consumer/keeper/changeover.go +++ b/x/ccv/consumer/keeper/changeover.go @@ -48,5 +48,6 @@ func (k Keeper) ChangeoverToConsumer(ctx sdk.Context) (initialValUpdates []abci. // Therefore we set the PreCCV state to false so the endblocker caller doesn't call this method again. k.DeletePreCCV(ctx) + k.Logger(ctx).Info("ICS changeover complete - you are now a consumer chain!") return initialValUpdates } diff --git a/x/ccv/consumer/keeper/changeover_test.go b/x/ccv/consumer/keeper/changeover_test.go index b45a60ba1a..9296dcb951 100644 --- a/x/ccv/consumer/keeper/changeover_test.go +++ b/x/ccv/consumer/keeper/changeover_test.go @@ -6,8 +6,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" sdkcryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/testutil/crypto" - uthelpers "github.com/cosmos/interchain-security/testutil/keeper" + "github.com/cosmos/interchain-security/v2/testutil/crypto" + uthelpers "github.com/cosmos/interchain-security/v2/testutil/keeper" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/ccv/consumer/keeper/distribution.go b/x/ccv/consumer/keeper/distribution.go index cb92cce238..fac98c3cfc 100644 --- a/x/ccv/consumer/keeper/distribution.go +++ b/x/ccv/consumer/keeper/distribution.go @@ -4,15 +4,15 @@ import ( "fmt" "strconv" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // EndBlockRD executes EndBlock logic for the Reward Distribution sub-protocol. @@ -107,28 +107,34 @@ func (k Keeper) SendRewardsToProvider(ctx sdk.Context) error { if found && transferChannel.State == channeltypes.OPEN { tstProviderAddr := k.authKeeper.GetModuleAccount(ctx, types.ConsumerToSendToProviderName).GetAddress() - tstProviderTokens := k.bankKeeper.GetAllBalances(ctx, tstProviderAddr) providerAddr := k.GetProviderFeePoolAddrStr(ctx) timeoutHeight := clienttypes.ZeroHeight() transferTimeoutPeriod := k.GetTransferTimeoutPeriod(ctx) timeoutTimestamp := uint64(ctx.BlockTime().Add(transferTimeoutPeriod).UnixNano()) - for _, token := range tstProviderTokens { - packetTransfer := &transfertypes.MsgTransfer{ - SourcePort: transfertypes.PortID, - SourceChannel: ch, - Token: token, - Sender: tstProviderAddr.String(), // consumer address to send from - Receiver: providerAddr, // provider fee pool address to send to - TimeoutHeight: timeoutHeight, // timeout height disabled - TimeoutTimestamp: timeoutTimestamp, - Memo: "consumer chain rewards distribution", - } - _, err := k.ibcTransferKeeper.Transfer(ctx, packetTransfer) - if err != nil { - return err - } - if err != nil { - return err + + sentCoins := sdk.NewCoins() + // iterate over all whitelisted reward denoms + for _, denom := range k.AllowedRewardDenoms(ctx) { + // get the balance of the denom in the toSendToProviderTokens address + balance := k.bankKeeper.GetBalance(ctx, tstProviderAddr, denom) + + // if the balance is not zero, + if !balance.IsZero() { + packetTransfer := &transfertypes.MsgTransfer{ + SourcePort: transfertypes.PortID, + SourceChannel: ch, + Token: balance, + Sender: tstProviderAddr.String(), // consumer address to send from + Receiver: providerAddr, // provider fee pool address to send to + TimeoutHeight: timeoutHeight, // timeout height disabled + TimeoutTimestamp: timeoutTimestamp, + Memo: "consumer chain rewards distribution", + } + _, err := k.ibcTransferKeeper.Transfer(ctx, packetTransfer) + if err != nil { + return err + } + sentCoins = sentCoins.Add(balance) } } @@ -137,7 +143,7 @@ func (k Keeper) SendRewardsToProvider(ctx sdk.Context) error { k.Logger(ctx).Info("sent block rewards to provider", "total fee pool", fpTokens.String(), - "sent", tstProviderTokens.String(), + "sent", sentCoins.String(), ) currentHeight := ctx.BlockHeight() ctx.EventManager().EmitEvent( @@ -148,7 +154,7 @@ func (k Keeper) SendRewardsToProvider(ctx sdk.Context) error { sdk.NewAttribute(ccv.AttributeDistributionNextHeight, strconv.Itoa(int(currentHeight+k.GetBlocksPerDistributionTransmission(ctx)))), sdk.NewAttribute(ccv.AttributeDistributionFraction, (k.GetConsumerRedistributionFrac(ctx))), sdk.NewAttribute(ccv.AttributeDistributionTotal, fpTokens.String()), - sdk.NewAttribute(ccv.AttributeDistributionToProvider, tstProviderTokens.String()), + sdk.NewAttribute(ccv.AttributeDistributionToProvider, sentCoins.String()), ), ) } @@ -156,6 +162,34 @@ func (k Keeper) SendRewardsToProvider(ctx sdk.Context) error { return nil } +// AllowedRewardDenoms returns a list of all denoms that are allowed +// to be sent to the provider as rewards +func (k Keeper) AllowedRewardDenoms(ctx sdk.Context) []string { + var rewardDenoms []string + + // first, append the native reward denoms + rewardDenoms = append(rewardDenoms, k.GetRewardDenoms(ctx)...) + + // then, append the provider-originated reward denoms + for _, denom := range k.GetProviderRewardDenoms(ctx) { + // every provider denom was sent over IBC, + // so we must prefix the denom + sourcePrefix := transfertypes.GetDenomPrefix( + transfertypes.PortID, + k.GetDistributionTransmissionChannel(ctx), + ) + // NOTE: sourcePrefix contains the trailing "/" + prefixedDenom := sourcePrefix + denom + // construct the denomination trace from the full raw denomination + denomTrace := transfertypes.ParseDenomTrace(prefixedDenom) + + // append the IBC denom to the list of allowed reward denoms + rewardDenoms = append(rewardDenoms, denomTrace.IBCDenom()) + } + + return rewardDenoms +} + func (k Keeper) GetLastTransmissionBlockHeight(ctx sdk.Context) types.LastTransmissionBlockHeight { store := ctx.KVStore(k.storeKey) bz := store.Get(types.LastDistributionTransmissionKey()) @@ -191,7 +225,7 @@ func (k Keeper) TransferChannelExists(ctx sdk.Context, channelID string) bool { func (k Keeper) GetConnectionHops(ctx sdk.Context, srcPort, srcChan string) ([]string, error) { ch, found := k.channelKeeper.GetChannel(ctx, srcPort, srcChan) if !found { - return []string{}, sdkerrors.Wrapf(ccv.ErrChannelNotFound, + return []string{}, errorsmod.Wrapf(ccv.ErrChannelNotFound, "cannot get connection hops from non-existent channel") } return ch.ConnectionHops, nil diff --git a/x/ccv/consumer/keeper/distribution_test.go b/x/ccv/consumer/keeper/distribution_test.go index f43dd31c6c..bb09c7e26b 100644 --- a/x/ccv/consumer/keeper/distribution_test.go +++ b/x/ccv/consumer/keeper/distribution_test.go @@ -1,14 +1,15 @@ package keeper_test import ( + "strings" "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" authTypes "github.com/cosmos/cosmos-sdk/x/auth/types" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" "github.com/golang/mock/gomock" ) @@ -65,3 +66,25 @@ func TestGetEstimatedNextFeeDistribution(t *testing.T) { require.NotEmpty(t, res) require.EqualValues(t, expect, res, "fee distribution data does not match") } + +func TestAllowedRewardDenoms(t *testing.T) { + keeperParams := testkeeper.NewInMemKeeperParams(t) + ctx := keeperParams.Ctx + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mocks := testkeeper.NewMockedKeepers(ctrl) + consumerKeeper := testkeeper.NewInMemConsumerKeeper(keeperParams, mocks) + params := types.DefaultParams() + params.RewardDenoms = []string{"ustake"} + params.ProviderRewardDenoms = []string{"uatom"} + consumerKeeper.SetParams(ctx, params) + + transferChannelID := "channel-5" + consumerKeeper.SetDistributionTransmissionChannel(ctx, transferChannelID) + + allowedDenoms := consumerKeeper.AllowedRewardDenoms(ctx) + require.Len(t, allowedDenoms, 2) + require.Equal(t, allowedDenoms[0], "ustake") + require.True(t, strings.HasPrefix(allowedDenoms[1], "ibc/")) +} diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index d27c5e6e17..04c97dd4e3 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -4,8 +4,8 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" abci "github.com/cometbft/cometbft/abci/types" ) diff --git a/x/ccv/consumer/keeper/genesis_test.go b/x/ccv/consumer/keeper/genesis_test.go index f15967f754..f05d8c960f 100644 --- a/x/ccv/consumer/keeper/genesis_test.go +++ b/x/ccv/consumer/keeper/genesis_test.go @@ -8,19 +8,21 @@ import ( tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // TestInitGenesis tests that a consumer chain is correctly initialised from genesis. diff --git a/x/ccv/consumer/keeper/grpc_query.go b/x/ccv/consumer/keeper/grpc_query.go index 5dd93ba823..9658edf64c 100644 --- a/x/ccv/consumer/keeper/grpc_query.go +++ b/x/ccv/consumer/keeper/grpc_query.go @@ -4,7 +4,7 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/x/ccv/consumer/keeper/hooks.go b/x/ccv/consumer/keeper/hooks.go index 5b9e90df20..33a756d525 100644 --- a/x/ccv/consumer/keeper/hooks.go +++ b/x/ccv/consumer/keeper/hooks.go @@ -2,7 +2,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) var _ ccv.ConsumerHooks = Keeper{} diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index b932b8cd25..b50b330efa 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -6,7 +6,7 @@ import ( "reflect" "time" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -21,8 +21,9 @@ import ( "github.com/cometbft/cometbft/libs/log" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // Keeper defines the Cross-Chain Validation Consumer Keeper @@ -103,6 +104,12 @@ func (k *Keeper) SetStandaloneStakingKeeper(sk ccv.StakingKeeper) { k.standaloneStakingKeeper = sk } +// SetParamSpace sets the param space for the consumer keeper. +// Note: this is only used for testing! +func (k *Keeper) SetParamSpace(ctx sdk.Context, ps paramtypes.Subspace) { + k.paramStore = ps +} + // Validates that the consumer keeper is initialized with non-zero and // non-nil values for all its fields. Otherwise this method will panic. func (k Keeper) mustValidateFields() { @@ -154,7 +161,7 @@ func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { capName := host.ChannelCapabilityPath(portID, channelID) chanCap, ok := k.scopedKeeper.GetCapability(ctx, capName) if !ok { - return sdkerrors.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName) + return errorsmod.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName) } return k.channelKeeper.ChanCloseInit(ctx, portID, channelID, chanCap) } @@ -413,20 +420,20 @@ func (k Keeper) DeletePacketMaturityTimes(ctx sdk.Context, vscId uint64, maturit // is the expected provider chain. func (k Keeper) VerifyProviderChain(ctx sdk.Context, connectionHops []string) error { if len(connectionHops) != 1 { - return sdkerrors.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") + return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") } connectionID := connectionHops[0] conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) if !ok { - return sdkerrors.Wrapf(conntypes.ErrConnectionNotFound, "connection not found for connection ID: %s", connectionID) + return errorsmod.Wrapf(conntypes.ErrConnectionNotFound, "connection not found for connection ID: %s", connectionID) } // Verify that client id is expected clientID expectedClientId, ok := k.GetProviderClientID(ctx) if !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not find provider client id") + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "could not find provider client id") } if expectedClientId != conn.ClientId { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "invalid client: %s, channel must be built on top of client: %s", conn.ClientId, expectedClientId) + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "invalid client: %s, channel must be built on top of client: %s", conn.ClientId, expectedClientId) } return nil @@ -638,17 +645,3 @@ func (k Keeper) IsPrevStandaloneChain(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) return store.Has(types.PrevStandaloneChainKey()) } - -// SetStandaloneTransferChannelID sets the channelID of an existing transfer channel, -// for a chain which used to be a standalone chain. -func (k Keeper) SetStandaloneTransferChannelID(ctx sdk.Context, channelID string) { - store := ctx.KVStore(k.storeKey) - store.Set(types.StandaloneTransferChannelIDKey(), []byte(channelID)) -} - -// GetStandaloneTransferChannelID returns the channelID of an existing transfer channel, -// for a chain which used to be a standalone chain. -func (k Keeper) GetStandaloneTransferChannelID(ctx sdk.Context) string { - store := ctx.KVStore(k.storeKey) - return string(store.Get(types.StandaloneTransferChannelIDKey())) -} diff --git a/x/ccv/consumer/keeper/keeper_test.go b/x/ccv/consumer/keeper/keeper_test.go index 6638ed3671..c6443958b6 100644 --- a/x/ccv/consumer/keeper/keeper_test.go +++ b/x/ccv/consumer/keeper/keeper_test.go @@ -10,11 +10,13 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -541,19 +543,6 @@ func TestGetAllOutstandingDowntimes(t *testing.T) { require.Equal(t, result, expectedGetAllOrder) } -// TestStandaloneTransferChannelID tests the getter and setter for the existing transfer channel id -func TestStandaloneTransferChannelID(t *testing.T) { - ck, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // Test that the default value is empty - require.Equal(t, "", ck.GetStandaloneTransferChannelID(ctx)) - - // Test that the value can be set and retrieved - ck.SetStandaloneTransferChannelID(ctx, "channelID1234") - require.Equal(t, "channelID1234", ck.GetStandaloneTransferChannelID(ctx)) -} - func TestPrevStandaloneChainFlag(t *testing.T) { ck, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() diff --git a/x/ccv/consumer/keeper/params.go b/x/ccv/consumer/keeper/params.go index dbf74833e9..ad1a0f2cb5 100644 --- a/x/ccv/consumer/keeper/params.go +++ b/x/ccv/consumer/keeper/params.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // GetParams returns the params for the consumer ccv module @@ -24,6 +24,8 @@ func (k Keeper) GetConsumerParams(ctx sdk.Context) types.Params { k.GetHistoricalEntries(ctx), k.GetUnbondingPeriod(ctx), k.GetSoftOptOutThreshold(ctx), + k.GetRewardDenoms(ctx), + k.GetProviderRewardDenoms(ctx), ) } @@ -125,3 +127,15 @@ func (k Keeper) GetSoftOptOutThreshold(ctx sdk.Context) string { k.paramStore.Get(ctx, types.KeySoftOptOutThreshold, &str) return str } + +func (k Keeper) GetRewardDenoms(ctx sdk.Context) []string { + var denoms []string + k.paramStore.Get(ctx, types.KeyRewardDenoms, &denoms) + return denoms +} + +func (k Keeper) GetProviderRewardDenoms(ctx sdk.Context) []string { + var denoms []string + k.paramStore.Get(ctx, types.KeyProviderRewardDenoms, &denoms) + return denoms +} diff --git a/x/ccv/consumer/keeper/params_test.go b/x/ccv/consumer/keeper/params_test.go index 70775266f5..d8dd63a1cb 100644 --- a/x/ccv/consumer/keeper/params_test.go +++ b/x/ccv/consumer/keeper/params_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" ) @@ -16,6 +16,8 @@ func TestParams(t *testing.T) { defer ctrl.Finish() consumerKeeper.SetParams(ctx, types.DefaultParams()) + var rewardDenoms []string + var provideRewardDenoms []string expParams := types.NewParams( false, 1000, @@ -27,6 +29,8 @@ func TestParams(t *testing.T) { types.DefaultHistoricalEntries, types.DefaultConsumerUnbondingPeriod, types.DefaultSoftOptOutThreshold, + rewardDenoms, + provideRewardDenoms, ) // these are the default params, IBC suite independently sets enabled=true params := consumerKeeper.GetConsumerParams(ctx) @@ -34,7 +38,7 @@ func TestParams(t *testing.T) { newParams := types.NewParams(false, 1000, "channel-2", "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", - 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, "0.05") + 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}) consumerKeeper.SetParams(ctx, newParams) params = consumerKeeper.GetConsumerParams(ctx) require.Equal(t, newParams, params) diff --git a/x/ccv/consumer/keeper/relay.go b/x/ccv/consumer/keeper/relay.go index a219292f86..f57891bf98 100644 --- a/x/ccv/consumer/keeper/relay.go +++ b/x/ccv/consumer/keeper/relay.go @@ -4,15 +4,16 @@ import ( "fmt" "strconv" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // OnRecvVSCPacket sets the pending validator set changes that will be flushed to ABCI on Endblock @@ -195,13 +196,17 @@ func (k Keeper) SendPackets(ctx sdk.Context) { ) if err != nil { if clienttypes.ErrClientNotActive.Is(err) { - k.Logger(ctx).Debug("IBC client is inactive, packet remains in queue", "type", p.Type.String()) + // IBC client is expired! // leave the packet data stored to be sent once the client is upgraded + k.Logger(ctx).Info("IBC client is expired, cannot send IBC packet; leaving packet data stored:", "type", p.Type.String()) return } - // something went wrong when sending the packet - // TODO do not panic if the send fails - panic(fmt.Errorf("packet could not be sent over IBC: %w", err)) + // Not able to send packet over IBC! + // Leave the packet data stored for the sent to be retried in the next block. + // Note that if VSCMaturedPackets are not sent for long enough, the provider + // will remove the consumer anyway. + k.Logger(ctx).Error("cannot send IBC packet; leaving packet data stored:", "type", p.Type.String(), "err", err.Error()) + return } } @@ -231,7 +236,7 @@ func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Pac // check if there is an established CCV channel to provider channelID, found := k.GetProviderChannel(ctx) if !found { - return sdkerrors.Wrapf(types.ErrNoProposerChannelId, "recv ErrorAcknowledgement on non-established channel %s", packet.SourceChannel) + return errorsmod.Wrapf(types.ErrNoProposerChannelId, "recv ErrorAcknowledgement on non-established channel %s", packet.SourceChannel) } if channelID != packet.SourceChannel { // Close the established CCV channel as well diff --git a/x/ccv/consumer/keeper/relay_test.go b/x/ccv/consumer/keeper/relay_test.go index 0df7de27e3..23b3d99339 100644 --- a/x/ccv/consumer/keeper/relay_test.go +++ b/x/ccv/consumer/keeper/relay_test.go @@ -12,13 +12,16 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -280,3 +283,27 @@ func TestOnAcknowledgementPacket(t *testing.T) { err = consumerKeeper.OnAcknowledgementPacket(ctx, packet, ack) require.Nil(t, err) } + +// TestSendPackets tests the SendPackets method failing +func TestSendPacketsFailure(t *testing.T) { + // Keeper setup + consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + consumerKeeper.SetProviderChannel(ctx, "consumerCCVChannelID") + consumerKeeper.SetParams(ctx, consumertypes.DefaultParams()) + + // Set some pending packets + consumerKeeper.SetPendingPackets(ctx, types.ConsumerPacketDataList{List: []types.ConsumerPacketData{ + {}, {}, {}, + }}) + + // Mock the channel keeper to return an error + gomock.InOrder( + mocks.MockChannelKeeper.EXPECT().GetChannel(ctx, types.ConsumerPortID, + "consumerCCVChannelID").Return(channeltypes.Channel{}, false).Times(1), + ) + + // No panic should occur, pending packets should not be cleared + consumerKeeper.SendPackets(ctx) + require.Equal(t, 3, len(consumerKeeper.GetPendingPackets(ctx).List)) +} diff --git a/x/ccv/consumer/keeper/soft_opt_out.go b/x/ccv/consumer/keeper/soft_opt_out.go index 4424766e20..26b490633d 100644 --- a/x/ccv/consumer/keeper/soft_opt_out.go +++ b/x/ccv/consumer/keeper/soft_opt_out.go @@ -5,7 +5,7 @@ import ( "sort" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // SetSmallestNonOptOutPower sets the smallest validator power that cannot soft opt out. diff --git a/x/ccv/consumer/keeper/soft_opt_out_test.go b/x/ccv/consumer/keeper/soft_opt_out_test.go index 836dd130d7..f243b917d7 100644 --- a/x/ccv/consumer/keeper/soft_opt_out_test.go +++ b/x/ccv/consumer/keeper/soft_opt_out_test.go @@ -4,9 +4,11 @@ import ( "testing" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/stretchr/testify/require" ) diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 6c7a869e18..0f0f246833 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -9,7 +9,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // diff --git a/x/ccv/consumer/keeper/validators_test.go b/x/ccv/consumer/keeper/validators_test.go index 24f87da4f5..c9ce541794 100644 --- a/x/ccv/consumer/keeper/validators_test.go +++ b/x/ccv/consumer/keeper/validators_test.go @@ -10,10 +10,10 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" "github.com/stretchr/testify/require" ) diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index e8cf09a922..0e87463884 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -6,6 +6,8 @@ import ( "fmt" abci "github.com/cometbft/cometbft/abci/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" @@ -17,10 +19,10 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - "github.com/cosmos/interchain-security/x/ccv/consumer/client/cli" - "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/client/cli" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) var ( @@ -85,13 +87,15 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic - keeper keeper.Keeper + keeper keeper.Keeper + paramSpace paramtypes.Subspace } // NewAppModule creates a new consumer module -func NewAppModule(k keeper.Keeper) AppModule { +func NewAppModule(k keeper.Keeper, paramSpace paramtypes.Subspace) AppModule { return AppModule{ - keeper: k, + keeper: k, + paramSpace: paramSpace, } } @@ -101,7 +105,6 @@ func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { } // RegisterServices registers module services. -// TODO func (am AppModule) RegisterServices(cfg module.Configurator) { consumertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) } @@ -122,7 +125,14 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { + // Note that v1.0.0 consumers should technically be on a different consensus version + // than v1.2.0-multiden and v2.0.0. However, Neutron was the first consumer to launch + // in prod, and they've started on v1.2.0-multiden (which has a ConsensusVersion of 1). + // + // v1.2.0-multiden and v2.0.0 are consensus compatible, so they need return the same ConsensusVersion of 1. + return 1 +} // BeginBlock implements the AppModule interface // Set the VSC ID for the subsequent block to the same value as the current block diff --git a/x/ccv/consumer/types/consumer.pb.go b/x/ccv/consumer/types/consumer.pb.go index 10828bc032..dd5d991666 100644 --- a/x/ccv/consumer/types/consumer.pb.go +++ b/x/ccv/consumer/types/consumer.pb.go @@ -10,7 +10,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - _ "github.com/cosmos/interchain-security/x/ccv/types" + _ "github.com/cosmos/interchain-security/v2/x/ccv/types" _ "google.golang.org/protobuf/types/known/durationpb" _ "google.golang.org/protobuf/types/known/timestamppb" io "io" @@ -64,9 +64,16 @@ type Params struct { // which should be smaller than that of the provider in general. UnbondingPeriod time.Duration `protobuf:"bytes,9,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For example, a - // value of 0.05 means that the validators in the bottom 5% of the set can opt out + // can opt out of running the consumer chain without being punished. For + // example, a value of 0.05 means that the validators in the bottom 5% of the + // set can opt out SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` + // Reward denoms. These are the denominations which are allowed to be sent to + // the provider as rewards. + RewardDenoms []string `protobuf:"bytes,11,rep,name=reward_denoms,json=rewardDenoms,proto3" json:"reward_denoms,omitempty"` + // Provider-originated reward denoms. These are denoms coming from the + // provider which are allowed to be used as rewards. e.g. "uatom" + ProviderRewardDenoms []string `protobuf:"bytes,12,rep,name=provider_reward_denoms,json=providerRewardDenoms,proto3" json:"provider_reward_denoms,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -172,6 +179,20 @@ func (m *Params) GetSoftOptOutThreshold() string { return "" } +func (m *Params) GetRewardDenoms() []string { + if m != nil { + return m.RewardDenoms + } + return nil +} + +func (m *Params) GetProviderRewardDenoms() []string { + if m != nil { + return m.ProviderRewardDenoms + } + return nil +} + // LastTransmissionBlockHeight is the last time validator holding // pools were transmitted to the provider chain type LastTransmissionBlockHeight struct { @@ -345,54 +366,57 @@ func init() { } var fileDescriptor_5b27a82b276e7f93 = []byte{ - // 742 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xcd, 0x6e, 0xe3, 0x36, - 0x10, 0xb6, 0x9a, 0x8d, 0x37, 0xcb, 0x6c, 0xd1, 0x5d, 0xad, 0x9b, 0xd5, 0xba, 0x80, 0xec, 0x75, - 0xf7, 0xe0, 0x4b, 0x64, 0xac, 0x83, 0x5e, 0x72, 0x5b, 0x3b, 0x0d, 0x92, 0xfe, 0xc5, 0x55, 0x8c, - 0x1c, 0xda, 0x03, 0x41, 0x51, 0xb4, 0x44, 0x44, 0x22, 0x05, 0x92, 0x52, 0xab, 0xb7, 0xc8, 0xb1, - 0x8f, 0xd0, 0xde, 0xfb, 0x10, 0x41, 0x4f, 0x39, 0xf6, 0x94, 0x16, 0xc9, 0x1b, 0xf4, 0x09, 0x0a, - 0x52, 0x92, 0x13, 0x27, 0x1b, 0x20, 0xb7, 0x19, 0x7c, 0xdf, 0x7c, 0x9c, 0x19, 0x7e, 0x24, 0x18, - 0x53, 0xa6, 0x88, 0xc0, 0x31, 0xa2, 0x0c, 0x4a, 0x82, 0x73, 0x41, 0x55, 0x39, 0xc2, 0xb8, 0x18, - 0x61, 0xce, 0x64, 0x9e, 0x12, 0x31, 0x2a, 0xde, 0x2f, 0x63, 0x2f, 0x13, 0x5c, 0x71, 0xfb, 0xcb, - 0x8f, 0xd4, 0x78, 0x18, 0x17, 0xde, 0x92, 0x57, 0xbc, 0xef, 0xbe, 0x7b, 0x48, 0x58, 0xeb, 0xe1, - 0xa2, 0x92, 0xea, 0xbe, 0x89, 0x38, 0x8f, 0x12, 0x32, 0x32, 0x59, 0x90, 0x2f, 0x46, 0x88, 0x95, - 0x35, 0xd4, 0x89, 0x78, 0xc4, 0x4d, 0x38, 0xd2, 0x51, 0x53, 0x80, 0xb9, 0x4c, 0xb9, 0x84, 0x15, - 0x50, 0x25, 0x35, 0xe4, 0xde, 0xd5, 0x0a, 0x73, 0x81, 0x14, 0xe5, 0xac, 0xc6, 0x7b, 0x77, 0x71, - 0x45, 0x53, 0x22, 0x15, 0x4a, 0xb3, 0x8a, 0x30, 0xf8, 0x63, 0x1d, 0xb4, 0x67, 0x48, 0xa0, 0x54, - 0xda, 0x0e, 0x78, 0x4a, 0x18, 0x0a, 0x12, 0x12, 0x3a, 0x56, 0xdf, 0x1a, 0x6e, 0xf8, 0x4d, 0x6a, - 0x1f, 0x81, 0x77, 0x41, 0xc2, 0xf1, 0xa9, 0x84, 0x19, 0x11, 0x30, 0xa4, 0x52, 0x09, 0x1a, 0xe4, - 0xfa, 0x18, 0xa8, 0x04, 0x62, 0x32, 0xa5, 0x52, 0x52, 0xce, 0x9c, 0x4f, 0xfa, 0xd6, 0x70, 0xcd, - 0x7f, 0x5b, 0x71, 0x67, 0x44, 0xec, 0xdd, 0x62, 0xce, 0x6f, 0x11, 0xed, 0x6f, 0xc0, 0xdb, 0x07, - 0x55, 0x20, 0x8e, 0x11, 0x63, 0x24, 0x71, 0xd6, 0xfa, 0xd6, 0xf0, 0x99, 0xdf, 0x0b, 0x1f, 0x10, - 0x99, 0x56, 0x34, 0x7b, 0x17, 0x74, 0x33, 0xc1, 0x0b, 0x1a, 0x12, 0x01, 0x17, 0x84, 0xc0, 0x8c, - 0xf3, 0x04, 0xa2, 0x30, 0x14, 0x50, 0x2a, 0xe1, 0x3c, 0x31, 0x22, 0x5b, 0x0d, 0x63, 0x9f, 0x90, - 0x19, 0xe7, 0xc9, 0x87, 0x30, 0x14, 0xc7, 0x4a, 0xd8, 0x3f, 0x02, 0x1b, 0xe3, 0x02, 0xea, 0xa5, - 0xf0, 0x5c, 0xe9, 0xe9, 0x28, 0x0f, 0x9d, 0xf5, 0xbe, 0x35, 0xdc, 0x1c, 0xbf, 0xf1, 0xaa, 0xdd, - 0x79, 0xcd, 0xee, 0xbc, 0xbd, 0x7a, 0xb7, 0x93, 0x8d, 0xf3, 0xcb, 0x5e, 0xeb, 0xb7, 0x7f, 0x7a, - 0x96, 0xff, 0x02, 0xe3, 0x62, 0x5e, 0x55, 0xcf, 0x4c, 0xb1, 0xfd, 0x33, 0x78, 0x6d, 0xa6, 0x59, - 0x10, 0x71, 0x57, 0xb7, 0xfd, 0x78, 0xdd, 0xcf, 0x1b, 0x8d, 0x55, 0xf1, 0x03, 0xd0, 0x6f, 0xfc, - 0x06, 0x05, 0x59, 0x59, 0xe1, 0x42, 0x20, 0xac, 0x03, 0xe7, 0xa9, 0x99, 0xd8, 0x6d, 0x78, 0xfe, - 0x0a, 0x6d, 0xbf, 0x66, 0xd9, 0xdb, 0xc0, 0x8e, 0xa9, 0x54, 0x5c, 0x50, 0x8c, 0x12, 0x48, 0x98, - 0x12, 0x94, 0x48, 0x67, 0xc3, 0x5c, 0xe0, 0xcb, 0x1b, 0xe4, 0xeb, 0x0a, 0xb0, 0x7f, 0x00, 0x2f, - 0x72, 0x16, 0x70, 0x16, 0x52, 0x16, 0x35, 0xe3, 0x3c, 0x7b, 0xfc, 0x38, 0x9f, 0x2d, 0x8b, 0xeb, - 0x41, 0x76, 0xc0, 0x96, 0xe4, 0x0b, 0x05, 0x79, 0xa6, 0xa0, 0xde, 0x90, 0x8a, 0x05, 0x91, 0x31, - 0x4f, 0x42, 0x07, 0x98, 0xf6, 0x5f, 0x69, 0xf4, 0x28, 0x53, 0x47, 0xb9, 0x9a, 0x37, 0xd0, 0xe0, - 0x2b, 0xf0, 0xc5, 0x77, 0x48, 0xaa, 0xdb, 0x26, 0x98, 0x68, 0xab, 0x1d, 0x10, 0x1a, 0xc5, 0xca, - 0xde, 0x02, 0xed, 0xd8, 0x44, 0xc6, 0xbe, 0x6b, 0x7e, 0x9d, 0x0d, 0x7e, 0xb7, 0xc0, 0xab, 0xa9, - 0xe0, 0x52, 0x4e, 0xf5, 0xc3, 0x3c, 0x41, 0x09, 0x0d, 0x91, 0xe2, 0x42, 0xfb, 0x5d, 0xdb, 0x84, - 0x48, 0x69, 0x0a, 0x9e, 0xfb, 0x4d, 0x6a, 0x77, 0xc0, 0x7a, 0xc6, 0x7f, 0x21, 0xa2, 0x36, 0x74, - 0x95, 0xd8, 0x08, 0xb4, 0xb3, 0x3c, 0x38, 0x25, 0xa5, 0x71, 0xe6, 0xe6, 0xb8, 0x73, 0x6f, 0xf2, - 0x0f, 0xac, 0x9c, 0xec, 0xfc, 0x77, 0xd9, 0x7b, 0x5d, 0xa2, 0x34, 0xd9, 0x1d, 0xe8, 0x2b, 0x20, - 0x4c, 0xe6, 0x12, 0x56, 0x75, 0x83, 0xbf, 0xfe, 0xdc, 0xee, 0xd4, 0xcf, 0x17, 0x8b, 0x32, 0x53, - 0xdc, 0x9b, 0xe5, 0xc1, 0xb7, 0xa4, 0xf4, 0x6b, 0xe1, 0x81, 0x02, 0x2f, 0xbf, 0x47, 0x2a, 0x17, - 0x94, 0x45, 0x27, 0xc7, 0xd3, 0x19, 0xc2, 0xa7, 0x44, 0xe9, 0x6e, 0x0a, 0x89, 0x0f, 0xab, 0x57, - 0xf9, 0xc4, 0xaf, 0x12, 0xfb, 0x10, 0x7c, 0x9a, 0x1a, 0xaa, 0x2a, 0x8d, 0xcf, 0x4c, 0xaf, 0x9b, - 0xe3, 0xee, 0xbd, 0xa6, 0xe6, 0xcd, 0x8b, 0xaf, 0xee, 0xe3, 0x4c, 0xdf, 0xc7, 0xf3, 0xa6, 0x54, - 0x83, 0x93, 0xf9, 0xf9, 0x95, 0x6b, 0x5d, 0x5c, 0xb9, 0xd6, 0xbf, 0x57, 0xae, 0x75, 0x76, 0xed, - 0xb6, 0x2e, 0xae, 0xdd, 0xd6, 0xdf, 0xd7, 0x6e, 0xeb, 0xa7, 0xdd, 0x88, 0xaa, 0x38, 0x0f, 0x3c, - 0xcc, 0xd3, 0xfa, 0xdf, 0x19, 0xdd, 0x7c, 0x71, 0xdb, 0xcb, 0x2f, 0xee, 0xd7, 0xd5, 0xdf, 0x53, - 0x95, 0x19, 0x91, 0x41, 0xdb, 0x74, 0xb0, 0xf3, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x71, 0xcd, - 0x22, 0x5f, 0x6e, 0x05, 0x00, 0x00, + // 786 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xcf, 0x6e, 0xdb, 0x36, + 0x18, 0x8f, 0x96, 0xd6, 0x4d, 0x98, 0x14, 0x6b, 0x59, 0x2f, 0x55, 0x33, 0x40, 0x76, 0xdd, 0x1e, + 0x7c, 0x89, 0x84, 0x3a, 0xdb, 0xa5, 0xc0, 0x0e, 0x8d, 0xb3, 0xa2, 0xdd, 0xbf, 0x78, 0xaa, 0xd1, + 0x01, 0xdb, 0x81, 0xa0, 0x28, 0x5a, 0x22, 0x22, 0x91, 0x02, 0x49, 0xa9, 0xd3, 0x7d, 0x0f, 0xd0, + 0xe3, 0x1e, 0x61, 0x0f, 0xb0, 0x87, 0x28, 0x76, 0xea, 0x71, 0xa7, 0x6e, 0x48, 0xde, 0x60, 0x4f, + 0x30, 0x90, 0x92, 0x5c, 0x3b, 0x6d, 0x80, 0xdc, 0xf8, 0xe9, 0xf7, 0xfb, 0x7e, 0xfa, 0xfe, 0x83, + 0x09, 0xe3, 0x9a, 0x4a, 0x92, 0x62, 0xc6, 0x91, 0xa2, 0xa4, 0x94, 0x4c, 0xd7, 0x01, 0x21, 0x55, + 0x40, 0x04, 0x57, 0x65, 0x4e, 0x65, 0x50, 0x3d, 0x5a, 0xbe, 0xfd, 0x42, 0x0a, 0x2d, 0xe0, 0x83, + 0x8f, 0xf8, 0xf8, 0x84, 0x54, 0xfe, 0x92, 0x57, 0x3d, 0xda, 0x7f, 0x78, 0x99, 0xb0, 0xd1, 0x23, + 0x55, 0x23, 0xb5, 0x7f, 0x2f, 0x11, 0x22, 0xc9, 0x68, 0x60, 0xad, 0xa8, 0x5c, 0x04, 0x98, 0xd7, + 0x2d, 0xd4, 0x4f, 0x44, 0x22, 0xec, 0x33, 0x30, 0xaf, 0xce, 0x81, 0x08, 0x95, 0x0b, 0x85, 0x1a, + 0xa0, 0x31, 0x5a, 0xc8, 0xbb, 0xa8, 0x15, 0x97, 0x12, 0x6b, 0x26, 0x78, 0x8b, 0x0f, 0x2e, 0xe2, + 0x9a, 0xe5, 0x54, 0x69, 0x9c, 0x17, 0x0d, 0x61, 0xf4, 0x5b, 0x0f, 0xf4, 0x66, 0x58, 0xe2, 0x5c, + 0x41, 0x17, 0xdc, 0xa0, 0x1c, 0x47, 0x19, 0x8d, 0x5d, 0x67, 0xe8, 0x8c, 0xb7, 0xc2, 0xce, 0x84, + 0x27, 0xe0, 0x61, 0x94, 0x09, 0x72, 0xaa, 0x50, 0x41, 0x25, 0x8a, 0x99, 0xd2, 0x92, 0x45, 0xa5, + 0xf9, 0x0d, 0xd2, 0x12, 0x73, 0x95, 0x33, 0xa5, 0x98, 0xe0, 0xee, 0x27, 0x43, 0x67, 0xbc, 0x19, + 0xde, 0x6f, 0xb8, 0x33, 0x2a, 0x8f, 0x57, 0x98, 0xf3, 0x15, 0x22, 0xfc, 0x06, 0xdc, 0xbf, 0x54, + 0x05, 0x91, 0x14, 0x73, 0x4e, 0x33, 0x77, 0x73, 0xe8, 0x8c, 0xb7, 0xc3, 0x41, 0x7c, 0x89, 0xc8, + 0xb4, 0xa1, 0xc1, 0xc7, 0x60, 0xbf, 0x90, 0xa2, 0x62, 0x31, 0x95, 0x68, 0x41, 0x29, 0x2a, 0x84, + 0xc8, 0x10, 0x8e, 0x63, 0x89, 0x94, 0x96, 0xee, 0x35, 0x2b, 0xb2, 0xd7, 0x31, 0x9e, 0x52, 0x3a, + 0x13, 0x22, 0x7b, 0x12, 0xc7, 0xf2, 0x85, 0x96, 0xf0, 0x47, 0x00, 0x09, 0xa9, 0x90, 0x29, 0x8a, + 0x28, 0xb5, 0xc9, 0x8e, 0x89, 0xd8, 0xbd, 0x3e, 0x74, 0xc6, 0x3b, 0x93, 0x7b, 0x7e, 0x53, 0x3b, + 0xbf, 0xab, 0x9d, 0x7f, 0xdc, 0xd6, 0xf6, 0x68, 0xeb, 0xcd, 0xbb, 0xc1, 0xc6, 0xef, 0xff, 0x0c, + 0x9c, 0xf0, 0x16, 0x21, 0xd5, 0xbc, 0xf1, 0x9e, 0x59, 0x67, 0xf8, 0x0b, 0xb8, 0x6b, 0xb3, 0x59, + 0x50, 0x79, 0x51, 0xb7, 0x77, 0x75, 0xdd, 0xcf, 0x3a, 0x8d, 0x75, 0xf1, 0x67, 0x60, 0xd8, 0xcd, + 0x1b, 0x92, 0x74, 0xad, 0x84, 0x0b, 0x89, 0x89, 0x79, 0xb8, 0x37, 0x6c, 0xc6, 0x5e, 0xc7, 0x0b, + 0xd7, 0x68, 0x4f, 0x5b, 0x16, 0x3c, 0x00, 0x30, 0x65, 0x4a, 0x0b, 0xc9, 0x08, 0xce, 0x10, 0xe5, + 0x5a, 0x32, 0xaa, 0xdc, 0x2d, 0xdb, 0xc0, 0xdb, 0xef, 0x91, 0xaf, 0x1b, 0x00, 0xfe, 0x00, 0x6e, + 0x95, 0x3c, 0x12, 0x3c, 0x66, 0x3c, 0xe9, 0xd2, 0xd9, 0xbe, 0x7a, 0x3a, 0x9f, 0x2e, 0x9d, 0xdb, + 0x44, 0x0e, 0xc1, 0x9e, 0x12, 0x0b, 0x8d, 0x44, 0xa1, 0x91, 0xa9, 0x90, 0x4e, 0x25, 0x55, 0xa9, + 0xc8, 0x62, 0x17, 0xd8, 0xf0, 0xef, 0x18, 0xf4, 0xa4, 0xd0, 0x27, 0xa5, 0x9e, 0x77, 0x10, 0x7c, + 0x00, 0x6e, 0x4a, 0xfa, 0x0a, 0xcb, 0x18, 0xc5, 0x94, 0x8b, 0x5c, 0xb9, 0x3b, 0xc3, 0xcd, 0xf1, + 0x76, 0xb8, 0xdb, 0x7c, 0x3c, 0xb6, 0xdf, 0xe0, 0x17, 0x60, 0xd9, 0x6c, 0xb4, 0xce, 0xde, 0xb5, + 0xec, 0x7e, 0x87, 0x86, 0x2b, 0x5e, 0xa3, 0x2f, 0xc1, 0xe7, 0xdf, 0x61, 0xa5, 0x57, 0xe7, 0xeb, + 0xc8, 0x4c, 0xf1, 0x33, 0xca, 0x92, 0x54, 0xc3, 0x3d, 0xd0, 0x4b, 0xed, 0xcb, 0x6e, 0xc6, 0x66, + 0xd8, 0x5a, 0xa3, 0x3f, 0x1c, 0x70, 0x67, 0x2a, 0x85, 0x52, 0x53, 0xb3, 0xf3, 0x2f, 0x71, 0xc6, + 0x62, 0xac, 0x85, 0x34, 0xab, 0x64, 0x26, 0x90, 0x2a, 0x65, 0x1d, 0x76, 0xc3, 0xce, 0x84, 0x7d, + 0x70, 0xbd, 0x10, 0xaf, 0xa8, 0x6c, 0x77, 0xa5, 0x31, 0x20, 0x06, 0xbd, 0xa2, 0x8c, 0x4e, 0x69, + 0x6d, 0x87, 0x7e, 0x67, 0xd2, 0xff, 0xa0, 0xa8, 0x4f, 0x78, 0x7d, 0x74, 0xf8, 0xdf, 0xbb, 0xc1, + 0xdd, 0x1a, 0xe7, 0xd9, 0xe3, 0x91, 0xe9, 0x2e, 0xe5, 0xaa, 0x54, 0xa8, 0xf1, 0x1b, 0xfd, 0xf5, + 0xe7, 0x41, 0xbf, 0xbd, 0x0c, 0x44, 0xd6, 0x85, 0x16, 0xfe, 0xac, 0x8c, 0xbe, 0xa5, 0x75, 0xd8, + 0x0a, 0x8f, 0x34, 0xb8, 0xfd, 0x3d, 0xd6, 0xa5, 0x64, 0x3c, 0x79, 0xf9, 0x62, 0x3a, 0xc3, 0xe4, + 0x94, 0x6a, 0x13, 0x4d, 0xa5, 0xc8, 0xf3, 0x66, 0xe1, 0xaf, 0x85, 0x8d, 0x01, 0x9f, 0x83, 0x9b, + 0xb9, 0xa5, 0xea, 0xda, 0x8e, 0xb0, 0x8d, 0x75, 0x67, 0xb2, 0xff, 0x41, 0x50, 0xf3, 0xee, 0x98, + 0x34, 0xad, 0x7e, 0x6d, 0x5a, 0xbd, 0xdb, 0xb9, 0x1a, 0xf0, 0xe8, 0xa7, 0x37, 0x67, 0x9e, 0xf3, + 0xf6, 0xcc, 0x73, 0xfe, 0x3d, 0xf3, 0x9c, 0xd7, 0xe7, 0xde, 0xc6, 0xdb, 0x73, 0x6f, 0xe3, 0xef, + 0x73, 0x6f, 0xe3, 0xe7, 0xaf, 0x12, 0xa6, 0xd3, 0x32, 0xf2, 0x89, 0xc8, 0xdb, 0x93, 0x16, 0xbc, + 0xbf, 0x9e, 0x07, 0xcb, 0xeb, 0x59, 0x4d, 0x82, 0x5f, 0xd7, 0x6f, 0xb3, 0xae, 0x0b, 0xaa, 0xa2, + 0x9e, 0x0d, 0xe2, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x03, 0xd8, 0xe3, 0xcc, 0x05, + 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -415,6 +439,24 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ProviderRewardDenoms) > 0 { + for iNdEx := len(m.ProviderRewardDenoms) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ProviderRewardDenoms[iNdEx]) + copy(dAtA[i:], m.ProviderRewardDenoms[iNdEx]) + i = encodeVarintConsumer(dAtA, i, uint64(len(m.ProviderRewardDenoms[iNdEx]))) + i-- + dAtA[i] = 0x62 + } + } + if len(m.RewardDenoms) > 0 { + for iNdEx := len(m.RewardDenoms) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.RewardDenoms[iNdEx]) + copy(dAtA[i:], m.RewardDenoms[iNdEx]) + i = encodeVarintConsumer(dAtA, i, uint64(len(m.RewardDenoms[iNdEx]))) + i-- + dAtA[i] = 0x5a + } + } if len(m.SoftOptOutThreshold) > 0 { i -= len(m.SoftOptOutThreshold) copy(dAtA[i:], m.SoftOptOutThreshold) @@ -649,6 +691,18 @@ func (m *Params) Size() (n int) { if l > 0 { n += 1 + l + sovConsumer(uint64(l)) } + if len(m.RewardDenoms) > 0 { + for _, s := range m.RewardDenoms { + l = len(s) + n += 1 + l + sovConsumer(uint64(l)) + } + } + if len(m.ProviderRewardDenoms) > 0 { + for _, s := range m.ProviderRewardDenoms { + l = len(s) + n += 1 + l + sovConsumer(uint64(l)) + } + } return n } @@ -1018,6 +1072,70 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.SoftOptOutThreshold = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardDenoms", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsumer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthConsumer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsumer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RewardDenoms = append(m.RewardDenoms, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderRewardDenoms", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsumer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthConsumer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsumer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderRewardDenoms = append(m.ProviderRewardDenoms, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipConsumer(dAtA[iNdEx:]) diff --git a/x/ccv/consumer/types/errors.go b/x/ccv/consumer/types/errors.go index 718f4b309b..85e5088fa4 100644 --- a/x/ccv/consumer/types/errors.go +++ b/x/ccv/consumer/types/errors.go @@ -1,10 +1,11 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" ) // Consumer sentinel errors var ( - ErrNoProposerChannelId = sdkerrors.Register(ModuleName, 1, "no established CCV channel") + ErrNoProposerChannelId = errorsmod.Register(ModuleName, 1, "no established CCV channel") + ErrConsumerRewardDenomAlreadyRegistered = errorsmod.Register(ModuleName, 2, "consumer reward denom already registered") ) diff --git a/x/ccv/consumer/types/genesis.go b/x/ccv/consumer/types/genesis.go index f6a0c54173..54f6fe9651 100644 --- a/x/ccv/consumer/types/genesis.go +++ b/x/ccv/consumer/types/genesis.go @@ -1,11 +1,11 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" + abci "github.com/cometbft/cometbft/abci/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ccv "github.com/cosmos/interchain-security/x/ccv/types" - abci "github.com/cometbft/cometbft/abci/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // NewInitialGenesisState returns a consumer GenesisState for a completely new consumer chain. @@ -76,7 +76,7 @@ func (gs GenesisState) Validate() error { return nil } if len(gs.InitialValSet) == 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "initial validator set is empty") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "initial validator set is empty") } if err := gs.Params.Validate(); err != nil { return err @@ -84,72 +84,72 @@ func (gs GenesisState) Validate() error { if gs.NewChain { if gs.ProviderClientState == nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain") } if err := gs.ProviderClientState.Validate(); err != nil { - return sdkerrors.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) } if gs.ProviderConsensusState == nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") } if err := gs.ProviderConsensusState.ValidateBasic(); err != nil { - return sdkerrors.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) } if gs.ProviderClientId != "" { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") } if gs.ProviderChannelId != "" { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") } if len(gs.MaturingPackets) != 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "maturing packets must be empty for new chain") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "maturing packets must be empty for new chain") } if len(gs.PendingConsumerPackets.List) != 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "pending consumer packets must be empty for new chain") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "pending consumer packets must be empty for new chain") } if gs.LastTransmissionBlockHeight.Height != 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "last transmission block height must be empty for new chain") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "last transmission block height must be empty for new chain") } } else { // NOTE: For restart genesis, we will verify initial validator set in InitGenesis. if gs.ProviderClientId == "" { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state") } // handshake is still in progress handshakeInProgress := gs.ProviderChannelId == "" if handshakeInProgress { if len(gs.MaturingPackets) != 0 { - return sdkerrors.Wrap( + return errorsmod.Wrap( ccv.ErrInvalidGenesis, "maturing packets must be empty when handshake isn't completed") } if len(gs.OutstandingDowntimeSlashing) != 0 { - return sdkerrors.Wrap( + return errorsmod.Wrap( ccv.ErrInvalidGenesis, "outstanding downtime must be empty when handshake isn't completed") } if gs.LastTransmissionBlockHeight.Height != 0 { - return sdkerrors.Wrap( + return errorsmod.Wrap( ccv.ErrInvalidGenesis, "last transmission block height must be zero when handshake isn't completed") } if len(gs.PendingConsumerPackets.List) != 0 { for _, packet := range gs.PendingConsumerPackets.List { if packet.Type == ccv.VscMaturedPacket { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "pending maturing packets must be empty when handshake isn't completed") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "pending maturing packets must be empty when handshake isn't completed") } } } } if gs.HeightToValsetUpdateId == nil { - return sdkerrors.Wrap( + return errorsmod.Wrap( ccv.ErrInvalidGenesis, "empty height to validator set update id mapping", ) } if gs.ProviderClientState != nil || gs.ProviderConsensusState != nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") } for _, mat := range gs.MaturingPackets { if err := mat.Validate(); err != nil { - return sdkerrors.Wrap(err, "invalid unbonding sequences") + return errorsmod.Wrap(err, "invalid unbonding sequences") } } } @@ -158,10 +158,10 @@ func (gs GenesisState) Validate() error { func (mat MaturingVSCPacket) Validate() error { if mat.MaturityTime.IsZero() { - return sdkerrors.Wrap(ccv.ErrInvalidVSCMaturedTime, "cannot have 0 maturity time") + return errorsmod.Wrap(ccv.ErrInvalidVSCMaturedTime, "cannot have 0 maturity time") } if mat.VscId == 0 { - return sdkerrors.Wrap(ccv.ErrInvalidVSCMaturedId, "cannot have 0 maturity time") + return errorsmod.Wrap(ccv.ErrInvalidVSCMaturedId, "cannot have 0 maturity time") } return nil } diff --git a/x/ccv/consumer/types/genesis.pb.go b/x/ccv/consumer/types/genesis.pb.go index 368dbc96c0..cbf6675902 100644 --- a/x/ccv/consumer/types/genesis.pb.go +++ b/x/ccv/consumer/types/genesis.pb.go @@ -10,7 +10,7 @@ import ( proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - types1 "github.com/cosmos/interchain-security/x/ccv/types" + types1 "github.com/cosmos/interchain-security/v2/x/ccv/types" _ "google.golang.org/protobuf/types/known/durationpb" io "io" math "math" @@ -288,56 +288,57 @@ func init() { } var fileDescriptor_2db73a6057a27482 = []byte{ - // 782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcf, 0x6f, 0xeb, 0x34, - 0x1c, 0x6f, 0xde, 0x1b, 0xa5, 0xf5, 0xde, 0xe3, 0x0d, 0x0f, 0xaa, 0xd0, 0x8a, 0x50, 0x06, 0x87, - 0x4a, 0x40, 0xa2, 0x16, 0x09, 0x21, 0x90, 0x10, 0xac, 0x93, 0xa0, 0xd2, 0x80, 0xa9, 0xdd, 0x7a, - 0xd8, 0x25, 0x72, 0x1d, 0x93, 0x58, 0x4b, 0xec, 0xc8, 0x76, 0x32, 0x76, 0xe0, 0xc2, 0x95, 0x0b, - 0x7f, 0xd6, 0x8e, 0x3b, 0x72, 0x42, 0x68, 0xfb, 0x1f, 0x38, 0xa3, 0xd8, 0x4e, 0x7f, 0xb0, 0x4e, - 0xaf, 0xa7, 0xc4, 0xf9, 0x7e, 0x7e, 0x7c, 0x7f, 0x38, 0x36, 0x18, 0x52, 0xa6, 0x88, 0xc0, 0x09, - 0xa2, 0x2c, 0x94, 0x04, 0x17, 0x82, 0xaa, 0x9b, 0x00, 0xe3, 0x32, 0xc0, 0x9c, 0xc9, 0x22, 0x23, - 0x22, 0x28, 0x87, 0x41, 0x4c, 0x18, 0x91, 0x54, 0xfa, 0xb9, 0xe0, 0x8a, 0xc3, 0x8f, 0xb6, 0x50, - 0x7c, 0x8c, 0x4b, 0xbf, 0xa6, 0xf8, 0xe5, 0xb0, 0xfb, 0xf1, 0x53, 0xba, 0xe5, 0xb0, 0x7a, 0x18, - 0xa9, 0xee, 0x68, 0x17, 0xf7, 0xa5, 0xac, 0xe1, 0xf4, 0x14, 0x61, 0x11, 0x11, 0x19, 0x65, 0x2a, - 0x40, 0x0b, 0x4c, 0x03, 0x75, 0x93, 0x13, 0x9b, 0x5b, 0x37, 0xa0, 0x0b, 0x1c, 0xa4, 0x34, 0x4e, - 0x14, 0x4e, 0x29, 0x61, 0x4a, 0x06, 0x6b, 0xe8, 0x72, 0xb8, 0xb6, 0xb2, 0x84, 0x0f, 0x2b, 0x02, - 0xe6, 0x82, 0x04, 0x38, 0x41, 0x8c, 0x91, 0x54, 0x3b, 0x9a, 0x57, 0x0b, 0xf1, 0x62, 0xce, 0xe3, - 0x94, 0x04, 0x7a, 0xb5, 0x28, 0x7e, 0x09, 0xa2, 0x42, 0x20, 0x45, 0x39, 0xb3, 0xf1, 0x77, 0x62, - 0x1e, 0x73, 0xfd, 0x1a, 0x54, 0x6f, 0xe6, 0xeb, 0xd1, 0xbf, 0x2d, 0xf0, 0xe2, 0x7b, 0xd3, 0xb7, - 0x99, 0x42, 0x8a, 0xc0, 0x09, 0x68, 0xe6, 0x48, 0xa0, 0x4c, 0xba, 0x4e, 0xdf, 0x19, 0xec, 0x8f, - 0x3e, 0xf1, 0x77, 0xe8, 0xa3, 0x7f, 0xa6, 0x29, 0xc7, 0x7b, 0xb7, 0x7f, 0x7f, 0xd0, 0x98, 0x5a, - 0x01, 0xf8, 0x29, 0x80, 0xb9, 0xe0, 0x25, 0x8d, 0x88, 0x08, 0x4d, 0x9d, 0x21, 0x8d, 0xdc, 0x67, - 0x7d, 0x67, 0xd0, 0x9e, 0x1e, 0xd4, 0x91, 0xb1, 0x0e, 0x4c, 0x22, 0xe8, 0x83, 0xc3, 0x15, 0xda, - 0x54, 0x56, 0xc1, 0x9f, 0x6b, 0xf8, 0xdb, 0x4b, 0xb8, 0x89, 0x4c, 0x22, 0xd8, 0x03, 0x6d, 0x46, - 0xae, 0x43, 0x9d, 0x98, 0xbb, 0xd7, 0x77, 0x06, 0xad, 0x69, 0x8b, 0x91, 0xeb, 0x71, 0xb5, 0x86, - 0x21, 0x78, 0xf7, 0xff, 0xd6, 0xb2, 0x2a, 0xcf, 0x7d, 0xa3, 0x2e, 0x6a, 0x81, 0xfd, 0xf5, 0x01, - 0xf8, 0x6b, 0x2d, 0x2f, 0x87, 0xbe, 0xc9, 0x4a, 0x77, 0x64, 0x7a, 0xb8, 0x99, 0xaa, 0x69, 0x53, - 0x02, 0xdc, 0x95, 0x01, 0x67, 0x92, 0x30, 0x59, 0x48, 0xeb, 0xd1, 0xd4, 0x1e, 0xfe, 0x6b, 0x3d, - 0x6a, 0x9a, 0xb1, 0xe9, 0x2c, 0x6d, 0x36, 0xbe, 0xc3, 0x18, 0x1c, 0x64, 0x48, 0x15, 0x82, 0xb2, - 0x38, 0xcc, 0x11, 0xbe, 0x22, 0x4a, 0xba, 0x6f, 0xf6, 0x9f, 0x0f, 0xf6, 0x47, 0x5f, 0xec, 0x34, - 0x9a, 0x1f, 0x2d, 0x79, 0x3e, 0x1b, 0x9f, 0x69, 0xba, 0x9d, 0xd2, 0xab, 0x5a, 0xd5, 0x7c, 0x95, - 0xf0, 0x27, 0xf0, 0x8a, 0x32, 0xaa, 0x28, 0x4a, 0xc3, 0x12, 0xa5, 0xa1, 0x24, 0xca, 0x6d, 0x69, - 0x9f, 0xfe, 0x7a, 0xe2, 0xd5, 0x5e, 0xf6, 0xe7, 0x28, 0xa5, 0x11, 0x52, 0x5c, 0x5c, 0xe4, 0x11, - 0x52, 0xc4, 0x2a, 0xbe, 0xb4, 0xf4, 0x39, 0x4a, 0x67, 0x44, 0xc1, 0xdf, 0x40, 0x37, 0x21, 0x55, - 0xf9, 0xa1, 0xe2, 0x95, 0xa2, 0x24, 0x2a, 0x2c, 0x34, 0xbe, 0x9a, 0x6b, 0x5b, 0x4b, 0x7f, 0xbd, - 0x53, 0x09, 0x3f, 0x68, 0x99, 0x73, 0x3e, 0xd7, 0x22, 0xc6, 0x73, 0x72, 0x62, 0x5d, 0x3b, 0xc9, - 0xb6, 0x68, 0x04, 0x7f, 0x77, 0xc0, 0xfb, 0xbc, 0x50, 0x52, 0x21, 0x16, 0x55, 0xbd, 0x8b, 0xf8, - 0x35, 0x53, 0x34, 0x23, 0xa1, 0x4c, 0x91, 0x4c, 0x28, 0x8b, 0x5d, 0xa0, 0x53, 0xf8, 0x72, 0xa7, - 0x14, 0x7e, 0x5e, 0x29, 0x9d, 0x58, 0x21, 0xeb, 0xdf, 0xe3, 0x8f, 0x43, 0x33, 0x6b, 0x01, 0x05, - 0x70, 0x73, 0x62, 0xfc, 0x6b, 0xb5, 0xe5, 0x10, 0xf7, 0xf5, 0x36, 0x19, 0x3d, 0x69, 0x6f, 0xb7, - 0x48, 0xc5, 0x31, 0x23, 0x3a, 0x41, 0x0a, 0x9d, 0x52, 0x59, 0x0f, 0xb0, 0x63, 0x95, 0x37, 0x41, - 0x12, 0xfe, 0xe1, 0x00, 0x2f, 0x45, 0x52, 0x85, 0x4a, 0x20, 0x26, 0x33, 0x2a, 0x25, 0xe5, 0x2c, - 0x5c, 0xa4, 0x1c, 0x5f, 0x85, 0xa6, 0x57, 0xee, 0x0b, 0x6d, 0xfd, 0xed, 0x4e, 0x95, 0x9f, 0x22, - 0xa9, 0xce, 0xd7, 0x94, 0x8e, 0x2b, 0x21, 0x33, 0x91, 0xba, 0x03, 0xe9, 0xd3, 0x10, 0xd8, 0x01, - 0xcd, 0x5c, 0x90, 0xf1, 0x78, 0xee, 0xbe, 0xd4, 0xff, 0xa8, 0x5d, 0x1d, 0x5d, 0x82, 0xce, 0xf6, - 0xb1, 0x56, 0x0c, 0x9b, 0x66, 0x75, 0x02, 0xed, 0x4d, 0xed, 0x0a, 0x0e, 0xc0, 0xc1, 0xa3, 0x5d, - 0xf4, 0x4c, 0x23, 0xde, 0x2a, 0x37, 0x46, 0x7f, 0x74, 0x01, 0x0e, 0xb7, 0xcc, 0x0b, 0x7e, 0x03, - 0x7a, 0x65, 0xbd, 0x71, 0xd7, 0x7e, 0x5a, 0x14, 0x45, 0x82, 0x48, 0x73, 0xde, 0xb5, 0xa7, 0xef, - 0x2d, 0x21, 0xcb, 0xff, 0xf0, 0x3b, 0x03, 0x38, 0x3e, 0xbf, 0xbd, 0xf7, 0x9c, 0xbb, 0x7b, 0xcf, - 0xf9, 0xe7, 0xde, 0x73, 0xfe, 0x7c, 0xf0, 0x1a, 0x77, 0x0f, 0x5e, 0xe3, 0xaf, 0x07, 0xaf, 0x71, - 0xf9, 0x55, 0x4c, 0x55, 0x52, 0x2c, 0x7c, 0xcc, 0xb3, 0x00, 0x73, 0x99, 0x71, 0x19, 0xac, 0x5a, - 0xfb, 0xd9, 0xf2, 0xca, 0xf8, 0x75, 0xf3, 0xd2, 0xd0, 0x37, 0xc2, 0xa2, 0xa9, 0x0f, 0xe2, 0xcf, - 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xab, 0x08, 0x12, 0x9c, 0xe3, 0x06, 0x00, 0x00, + // 786 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4b, 0x8f, 0xe3, 0x34, + 0x1c, 0x6f, 0x76, 0x87, 0xd2, 0x7a, 0x76, 0xd9, 0xc1, 0x03, 0x55, 0x68, 0x45, 0x28, 0x03, 0x87, + 0x4a, 0x40, 0xac, 0x16, 0x09, 0x21, 0x21, 0x10, 0x4c, 0x47, 0x82, 0x4a, 0x0b, 0xac, 0xda, 0xdd, + 0x22, 0xed, 0x25, 0x72, 0x1d, 0x93, 0x58, 0x9b, 0xd8, 0x91, 0xed, 0x64, 0xd8, 0x03, 0x17, 0xae, + 0x5c, 0xf8, 0x58, 0x7b, 0x9c, 0x23, 0x27, 0x84, 0x66, 0xbe, 0x03, 0x67, 0x14, 0xdb, 0xe9, 0x83, + 0xe9, 0x88, 0x9e, 0x12, 0xe7, 0xff, 0x7b, 0xfc, 0x1f, 0x8e, 0x0d, 0xc6, 0x8c, 0x6b, 0x2a, 0x49, + 0x8a, 0x19, 0x8f, 0x14, 0x25, 0xa5, 0x64, 0xfa, 0x25, 0x22, 0xa4, 0x42, 0x44, 0x70, 0x55, 0xe6, + 0x54, 0xa2, 0x6a, 0x8c, 0x12, 0xca, 0xa9, 0x62, 0x2a, 0x2c, 0xa4, 0xd0, 0x02, 0x7e, 0xb0, 0x87, + 0x12, 0x12, 0x52, 0x85, 0x0d, 0x25, 0xac, 0xc6, 0xfd, 0x0f, 0xef, 0xd2, 0xad, 0xc6, 0xf5, 0xc3, + 0x4a, 0xf5, 0x27, 0x87, 0xb8, 0xaf, 0x65, 0x2d, 0x67, 0xa0, 0x29, 0x8f, 0xa9, 0xcc, 0x19, 0xd7, + 0x08, 0xaf, 0x08, 0x43, 0xfa, 0x65, 0x41, 0x5d, 0x6e, 0x7d, 0xc4, 0x56, 0x04, 0x65, 0x2c, 0x49, + 0x35, 0xc9, 0x18, 0xe5, 0x5a, 0xa1, 0x2d, 0x74, 0x35, 0xde, 0x5a, 0x39, 0xc2, 0xfb, 0x35, 0x81, + 0x08, 0x49, 0x11, 0x49, 0x31, 0xe7, 0x34, 0x33, 0x8e, 0xf6, 0xd5, 0x41, 0x82, 0x44, 0x88, 0x24, + 0xa3, 0xc8, 0xac, 0x56, 0xe5, 0xcf, 0x28, 0x2e, 0x25, 0xd6, 0x4c, 0x70, 0x17, 0x7f, 0x2b, 0x11, + 0x89, 0x30, 0xaf, 0xa8, 0x7e, 0xb3, 0x5f, 0xcf, 0xfe, 0xe9, 0x80, 0x07, 0xdf, 0xda, 0xbe, 0x2d, + 0x34, 0xd6, 0x14, 0xce, 0x40, 0xbb, 0xc0, 0x12, 0xe7, 0xca, 0xf7, 0x86, 0xde, 0xe8, 0x78, 0xf2, + 0x51, 0x78, 0x40, 0x1f, 0xc3, 0x27, 0x86, 0x72, 0x7e, 0xf4, 0xea, 0xaf, 0xf7, 0x5a, 0x73, 0x27, + 0x00, 0x3f, 0x06, 0xb0, 0x90, 0xa2, 0x62, 0x31, 0x95, 0x91, 0xad, 0x33, 0x62, 0xb1, 0x7f, 0x6f, + 0xe8, 0x8d, 0xba, 0xf3, 0x93, 0x26, 0x32, 0x35, 0x81, 0x59, 0x0c, 0x43, 0x70, 0xba, 0x41, 0xdb, + 0xca, 0x6a, 0xf8, 0x7d, 0x03, 0x7f, 0x73, 0x0d, 0xb7, 0x91, 0x59, 0x0c, 0x07, 0xa0, 0xcb, 0xe9, + 0x65, 0x64, 0x12, 0xf3, 0x8f, 0x86, 0xde, 0xa8, 0x33, 0xef, 0x70, 0x7a, 0x39, 0xad, 0xd7, 0x30, + 0x02, 0x6f, 0xff, 0xd7, 0x5a, 0xd5, 0xe5, 0xf9, 0xaf, 0x35, 0x45, 0xad, 0x48, 0xb8, 0x3d, 0x80, + 0x70, 0xab, 0xe5, 0xd5, 0x38, 0xb4, 0x59, 0x99, 0x8e, 0xcc, 0x4f, 0x77, 0x53, 0xb5, 0x6d, 0x4a, + 0x81, 0xbf, 0x31, 0x10, 0x5c, 0x51, 0xae, 0x4a, 0xe5, 0x3c, 0xda, 0xc6, 0x23, 0xfc, 0x5f, 0x8f, + 0x86, 0x66, 0x6d, 0x7a, 0x6b, 0x9b, 0x9d, 0xef, 0x30, 0x01, 0x27, 0x39, 0xd6, 0xa5, 0x64, 0x3c, + 0x89, 0x0a, 0x4c, 0x5e, 0x50, 0xad, 0xfc, 0xd7, 0x87, 0xf7, 0x47, 0xc7, 0x93, 0xcf, 0x0e, 0x1a, + 0xcd, 0xf7, 0x8e, 0xbc, 0x5c, 0x4c, 0x9f, 0x18, 0xba, 0x9b, 0xd2, 0xa3, 0x46, 0xd5, 0x7e, 0x55, + 0xf0, 0x07, 0xf0, 0x88, 0x71, 0xa6, 0x19, 0xce, 0xa2, 0x0a, 0x67, 0x91, 0xa2, 0xda, 0xef, 0x18, + 0x9f, 0xe1, 0x76, 0xe2, 0xf5, 0x5e, 0x0e, 0x97, 0x38, 0x63, 0x31, 0xd6, 0x42, 0x3e, 0x2b, 0x62, + 0xac, 0xa9, 0x53, 0x7c, 0xe8, 0xe8, 0x4b, 0x9c, 0x2d, 0xa8, 0x86, 0xbf, 0x82, 0x7e, 0x4a, 0xeb, + 0xf2, 0x23, 0x2d, 0x6a, 0x45, 0x45, 0x75, 0x54, 0x1a, 0x7c, 0x3d, 0xd7, 0xae, 0x91, 0xfe, 0xe2, + 0xa0, 0x12, 0xbe, 0x33, 0x32, 0x4f, 0xc5, 0xd2, 0x88, 0x58, 0xcf, 0xd9, 0x85, 0x73, 0xed, 0xa5, + 0xfb, 0xa2, 0x31, 0xfc, 0xcd, 0x03, 0xef, 0x8a, 0x52, 0x2b, 0x8d, 0x79, 0x5c, 0xf7, 0x2e, 0x16, + 0x97, 0x5c, 0xb3, 0x9c, 0x46, 0x2a, 0xc3, 0x2a, 0x65, 0x3c, 0xf1, 0x81, 0x49, 0xe1, 0xf3, 0x83, + 0x52, 0xf8, 0x71, 0xa3, 0x74, 0xe1, 0x84, 0x9c, 0xff, 0x40, 0xdc, 0x0e, 0x2d, 0x9c, 0x05, 0x94, + 0xc0, 0x2f, 0xa8, 0xf5, 0x6f, 0xd4, 0xd6, 0x43, 0x3c, 0x36, 0xdb, 0x64, 0x72, 0xa7, 0xbd, 0xdb, + 0x22, 0x35, 0xc7, 0x8e, 0xe8, 0x02, 0x6b, 0xfc, 0x98, 0xa9, 0x66, 0x80, 0x3d, 0xa7, 0xbc, 0x0b, + 0x52, 0xf0, 0x77, 0x0f, 0x04, 0x19, 0x56, 0x3a, 0xd2, 0x12, 0x73, 0x95, 0x33, 0xa5, 0x98, 0xe0, + 0xd1, 0x2a, 0x13, 0xe4, 0x45, 0x64, 0x7b, 0xe5, 0x3f, 0x30, 0xd6, 0x5f, 0x1f, 0x54, 0xf9, 0x63, + 0xac, 0xf4, 0xd3, 0x2d, 0xa5, 0xf3, 0x5a, 0xc8, 0x4e, 0xa4, 0xe9, 0x40, 0x76, 0x37, 0x04, 0xf6, + 0x40, 0xbb, 0x90, 0x74, 0x3a, 0x5d, 0xfa, 0x0f, 0xcd, 0x3f, 0xea, 0x56, 0x67, 0xcf, 0x41, 0x6f, + 0xff, 0x58, 0x6b, 0x86, 0x4b, 0xb3, 0x3e, 0x81, 0x8e, 0xe6, 0x6e, 0x05, 0x47, 0xe0, 0xe4, 0xd6, + 0x2e, 0xba, 0x67, 0x10, 0x6f, 0x54, 0x3b, 0xa3, 0x3f, 0x7b, 0x06, 0x4e, 0xf7, 0xcc, 0x0b, 0x7e, + 0x05, 0x06, 0x55, 0xb3, 0x71, 0xb7, 0x7e, 0x5a, 0x1c, 0xc7, 0x92, 0x2a, 0x7b, 0xde, 0x75, 0xe7, + 0xef, 0xac, 0x21, 0xeb, 0xff, 0xf0, 0x1b, 0x0b, 0x38, 0xff, 0xe9, 0xd5, 0x75, 0xe0, 0x5d, 0x5d, + 0x07, 0xde, 0xdf, 0xd7, 0x81, 0xf7, 0xc7, 0x4d, 0xd0, 0xba, 0xba, 0x09, 0x5a, 0x7f, 0xde, 0x04, + 0xad, 0xe7, 0x5f, 0x26, 0x4c, 0xa7, 0xe5, 0x2a, 0x24, 0x22, 0x47, 0x44, 0xa8, 0x5c, 0x28, 0xb4, + 0x69, 0xed, 0x27, 0xeb, 0x2b, 0xa3, 0x9a, 0xa0, 0x5f, 0x76, 0xef, 0x0d, 0x73, 0x29, 0xac, 0xda, + 0xe6, 0x2c, 0xfe, 0xf4, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x86, 0x37, 0xab, 0xfd, 0xe6, 0x06, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index d349b3df4a..af1badb73b 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -12,13 +12,13 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/testutil/crypto" + "github.com/cosmos/interchain-security/v2/testutil/crypto" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" ) @@ -210,7 +210,7 @@ func TestValidateInitialGenesisState(t *testing.T) { true, }, { - "invalid new consumer genesis state: invalid params", + "invalid new consumer genesis state: invalid params - ccvTimeoutPeriod", types.NewInitialGenesisState(cs, consensusState, valUpdates, types.NewParams( true, @@ -223,6 +223,27 @@ func TestValidateInitialGenesisState(t *testing.T) { types.DefaultHistoricalEntries, types.DefaultConsumerUnbondingPeriod, types.DefaultSoftOptOutThreshold, + []string{}, + []string{}, + )), + true, + }, + { + "invalid new consumer genesis state: invalid params - distributionTransmissionChannel", + types.NewInitialGenesisState(cs, consensusState, valUpdates, + types.NewParams( + true, + types.DefaultBlocksPerDistributionTransmission, + "badchannel/", + "", + ccv.DefaultCCVTimeoutPeriod, + types.DefaultTransferTimeoutPeriod, + types.DefaultConsumerRedistributeFrac, + types.DefaultHistoricalEntries, + types.DefaultConsumerUnbondingPeriod, + types.DefaultSoftOptOutThreshold, + []string{}, + []string{}, )), true, }, @@ -422,6 +443,8 @@ func TestValidateRestartGenesisState(t *testing.T) { types.DefaultHistoricalEntries, types.DefaultConsumerUnbondingPeriod, types.DefaultSoftOptOutThreshold, + []string{}, + []string{}, )), true, }, diff --git a/x/ccv/consumer/types/keys.go b/x/ccv/consumer/types/keys.go index e11390d9ed..093f78b450 100644 --- a/x/ccv/consumer/types/keys.go +++ b/x/ccv/consumer/types/keys.go @@ -5,7 +5,7 @@ import ( time "time" sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) const ( @@ -49,10 +49,8 @@ const ( // received over CCV channel but not yet flushed over ABCI PendingChangesByteKey - // PendingDataPacketsByteKey is the byte key for storing - // a list of data packets that cannot be sent yet to the provider - // chain either because the CCV channel is not established or - // because the client is expired + // NOTE: This prefix is depreciated, but left in place to avoid consumer state migrations + // [DEPRECATED] PendingDataPacketsByteKey // PreCCVByteKey is the byte to store the consumer is running on democracy staking module without consumer @@ -61,19 +59,13 @@ const ( // InitialValSetByteKey is the byte to store the initial validator set for a consumer InitialValSetByteKey - // InitGenesisHeightByteKey is the byte that will store the init genesis height - InitGenesisHeightByteKey + // NOTE: This prefix is depreciated, but left in place to avoid consumer state migrations + // [DEPRECATED] + LastStandaloneHeightByteKey // SmallestNonOptOutPowerByteKey is the byte that will store the smallest val power that cannot opt out SmallestNonOptOutPowerByteKey - // StandaloneTransferChannelIDByteKey is the byte storing the channelID of transfer channel - // that existed from a standalone chain changing over to a consumer - StandaloneTransferChannelIDByteKey - - // PrevStandaloneChainByteKey is the byte storing the flag marking whether this chain was previously standalone - PrevStandaloneChainByteKey - // HistoricalInfoKey is the byte prefix that will store the historical info for a given height HistoricalInfoBytePrefix @@ -86,9 +78,25 @@ const ( // OutstandingDowntimePrefix is the byte prefix that will store the validators outstanding downtime by consensus address OutstandingDowntimeBytePrefix + // PendingDataPacketsBytePrefix is the byte prefix for storing + // a list of data packets that cannot be sent yet to the provider + // chain either because the CCV channel is not established or + // because the client is expired + PendingDataPacketsBytePrefix + // CrossChainValidatorPrefix is the byte prefix that will store cross-chain validators by consensus address CrossChainValidatorBytePrefix + // InitGenesisHeightByteKey is the byte that will store the init genesis height + InitGenesisHeightByteKey + + // StandaloneTransferChannelIDByteKey is the byte storing the channelID of transfer channel + // that existed from a standalone chain changing over to a consumer + StandaloneTransferChannelIDByteKey + + // PrevStandaloneChainByteKey is the byte storing the flag marking whether this chain was previously standalone + PrevStandaloneChainByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -126,40 +134,6 @@ func PendingChangesKey() []byte { return []byte{PendingChangesByteKey} } -// PendingDataPacketsKey returns the key for storing a list of data packets -// that cannot be sent yet to the provider chain either because the CCV channel -// is not established or because the client is expired. -func PendingDataPacketsKey() []byte { - return []byte{PendingDataPacketsByteKey} -} - -func PreCCVKey() []byte { - return []byte{PreCCVByteKey} -} - -func InitialValSetKey() []byte { - return []byte{InitialValSetByteKey} -} - -func InitGenesisHeightKey() []byte { - return []byte{InitGenesisHeightByteKey} -} - -func SmallestNonOptOutPowerKey() []byte { - return []byte{SmallestNonOptOutPowerByteKey} -} - -// StandaloneTransferChannelIDKey returns the key to the transfer channelID that existed from a standalone chain -// changing over to a consumer -func StandaloneTransferChannelIDKey() []byte { - return []byte{StandaloneTransferChannelIDByteKey} -} - -// PrevStandaloneChainKey returns the key to the flag marking whether this chain was previously standalone -func PrevStandaloneChainKey() []byte { - return []byte{PrevStandaloneChainByteKey} -} - // HistoricalInfoKey returns the key to historical info to a given block height func HistoricalInfoKey(height int64) []byte { hBytes := make([]byte, 8) @@ -197,6 +171,40 @@ func CrossChainValidatorKey(addr []byte) []byte { return append([]byte{CrossChainValidatorBytePrefix}, addr...) } +// PendingDataPacketsKey returns the key for storing a list of data packets +// that cannot be sent yet to the provider chain either because the CCV channel +// is not established or because the client is expired. +func PendingDataPacketsKey() []byte { + return []byte{PendingDataPacketsBytePrefix} +} + +func PreCCVKey() []byte { + return []byte{PreCCVByteKey} +} + +func InitialValSetKey() []byte { + return []byte{InitialValSetByteKey} +} + +func InitGenesisHeightKey() []byte { + return []byte{InitGenesisHeightByteKey} +} + +func SmallestNonOptOutPowerKey() []byte { + return []byte{SmallestNonOptOutPowerByteKey} +} + +// StandaloneTransferChannelIDKey returns the key to the transfer channelID that existed from a standalone chain +// changing over to a consumer +func StandaloneTransferChannelIDKey() []byte { + return []byte{StandaloneTransferChannelIDByteKey} +} + +// PrevStandaloneChainKey returns the key to the flag marking whether this chain was previously standalone +func PrevStandaloneChainKey() []byte { + return []byte{PrevStandaloneChainByteKey} +} + // NOTE: DO NOT ADD FULLY DEFINED KEY FUNCTIONS WITHOUT ADDING THEM TO getAllFullyDefinedKeys() IN keys_test.go // diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index fc214380b9..a63da6f326 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -30,15 +30,17 @@ func getAllKeyPrefixes() []byte { PendingDataPacketsByteKey, PreCCVByteKey, InitialValSetByteKey, - InitGenesisHeightByteKey, + LastStandaloneHeightByteKey, SmallestNonOptOutPowerByteKey, - StandaloneTransferChannelIDByteKey, - PrevStandaloneChainByteKey, HistoricalInfoBytePrefix, PacketMaturityTimeBytePrefix, HeightValsetUpdateIDBytePrefix, OutstandingDowntimeBytePrefix, + PendingDataPacketsBytePrefix, CrossChainValidatorBytePrefix, + InitGenesisHeightByteKey, + StandaloneTransferChannelIDByteKey, + PrevStandaloneChainByteKey, } } @@ -61,17 +63,19 @@ func getAllFullyDefinedKeys() [][]byte { ProviderClientIDKey(), ProviderChannelKey(), PendingChangesKey(), - PendingDataPacketsKey(), + // PendingDataPacketsKey() does not use duplicated prefix with value of 0x06 PreCCVKey(), InitialValSetKey(), - InitGenesisHeightKey(), + // LastStandaloneHeightKey() is depreciated SmallestNonOptOutPowerKey(), - StandaloneTransferChannelIDKey(), - PrevStandaloneChainKey(), HistoricalInfoKey(0), PacketMaturityTimeKey(0, time.Time{}), HeightValsetUpdateIDKey(0), OutstandingDowntimeKey([]byte{}), + PendingDataPacketsKey(), CrossChainValidatorKey([]byte{}), + InitGenesisHeightKey(), + StandaloneTransferChannelIDKey(), + PrevStandaloneChainKey(), } } diff --git a/x/ccv/consumer/types/params.go b/x/ccv/consumer/types/params.go index 928900b207..7ab51fbad8 100644 --- a/x/ccv/consumer/types/params.go +++ b/x/ccv/consumer/types/params.go @@ -7,7 +7,7 @@ import ( sdktypes "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) const ( @@ -53,6 +53,8 @@ var ( KeyHistoricalEntries = []byte("HistoricalEntries") KeyConsumerUnbondingPeriod = []byte("UnbondingPeriod") KeySoftOptOutThreshold = []byte("SoftOptOutThreshold") + KeyRewardDenoms = []byte("RewardDenoms") + KeyProviderRewardDenoms = []byte("ProviderRewardDenoms") ) // ParamKeyTable type declaration for parameters @@ -65,7 +67,7 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, distributionTransmissionChannel, providerFeePoolAddrStr string, ccvTimeoutPeriod, transferTimeoutPeriod time.Duration, consumerRedistributionFraction string, historicalEntries int64, - consumerUnbondingPeriod time.Duration, softOptOutThreshold string, + consumerUnbondingPeriod time.Duration, softOptOutThreshold string, rewardDenoms, providerRewardDenoms []string, ) Params { return Params{ Enabled: enabled, @@ -78,11 +80,15 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, HistoricalEntries: historicalEntries, UnbondingPeriod: consumerUnbondingPeriod, SoftOptOutThreshold: softOptOutThreshold, + RewardDenoms: rewardDenoms, + ProviderRewardDenoms: providerRewardDenoms, } } // DefaultParams is the default params for the consumer module func DefaultParams() Params { + var rewardDenoms []string + var provideRewardDenoms []string return NewParams( false, DefaultBlocksPerDistributionTransmission, @@ -94,6 +100,8 @@ func DefaultParams() Params { DefaultHistoricalEntries, DefaultConsumerUnbondingPeriod, DefaultSoftOptOutThreshold, + rewardDenoms, + provideRewardDenoms, ) } @@ -105,10 +113,10 @@ func (p Params) Validate() error { if err := ccvtypes.ValidatePositiveInt64(p.BlocksPerDistributionTransmission); err != nil { return err } - if err := validateDistributionTransmissionChannel(p.DistributionTransmissionChannel); err != nil { + if err := ccvtypes.ValidateDistributionTransmissionChannel(p.DistributionTransmissionChannel); err != nil { return err } - if err := validateProviderFeePoolAddrStr(p.ProviderFeePoolAddrStr); err != nil { + if err := ValidateProviderFeePoolAddrStr(p.ProviderFeePoolAddrStr); err != nil { return err } if err := ccvtypes.ValidateDuration(p.CcvTimeoutPeriod); err != nil { @@ -126,7 +134,13 @@ func (p Params) Validate() error { if err := ccvtypes.ValidateDuration(p.UnbondingPeriod); err != nil { return err } - if err := validateSoftOptOutThreshold(p.SoftOptOutThreshold); err != nil { + if err := ValidateSoftOptOutThreshold(p.SoftOptOutThreshold); err != nil { + return err + } + if err := ValidateDenoms(p.RewardDenoms); err != nil { + return err + } + if err := ValidateDenoms(p.ProviderRewardDenoms); err != nil { return err } return nil @@ -139,9 +153,9 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyBlocksPerDistributionTransmission, p.BlocksPerDistributionTransmission, ccvtypes.ValidatePositiveInt64), paramtypes.NewParamSetPair(KeyDistributionTransmissionChannel, - p.DistributionTransmissionChannel, validateDistributionTransmissionChannel), + p.DistributionTransmissionChannel, ccvtypes.ValidateDistributionTransmissionChannel), paramtypes.NewParamSetPair(KeyProviderFeePoolAddrStr, - p.ProviderFeePoolAddrStr, validateProviderFeePoolAddrStr), + p.ProviderFeePoolAddrStr, ValidateProviderFeePoolAddrStr), paramtypes.NewParamSetPair(ccvtypes.KeyCCVTimeoutPeriod, p.CcvTimeoutPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeyTransferTimeoutPeriod, @@ -153,20 +167,15 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyConsumerUnbondingPeriod, p.UnbondingPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeySoftOptOutThreshold, - p.SoftOptOutThreshold, validateSoftOptOutThreshold), - } -} - -func validateDistributionTransmissionChannel(i interface{}) error { - // Accept empty string as valid, since this will be the default value on genesis - if i == "" { - return nil + p.SoftOptOutThreshold, ValidateSoftOptOutThreshold), + paramtypes.NewParamSetPair(KeyRewardDenoms, + p.RewardDenoms, ValidateDenoms), + paramtypes.NewParamSetPair(KeyProviderRewardDenoms, + p.ProviderRewardDenoms, ValidateDenoms), } - // Otherwise validate as usual for a channelID - return ccvtypes.ValidateChannelIdentifier(i) } -func validateProviderFeePoolAddrStr(i interface{}) error { +func ValidateProviderFeePoolAddrStr(i interface{}) error { // Accept empty string as valid, since this will be the default value on genesis if i == "" { return nil @@ -175,7 +184,7 @@ func validateProviderFeePoolAddrStr(i interface{}) error { return ccvtypes.ValidateBech32(i) } -func validateSoftOptOutThreshold(i interface{}) error { +func ValidateSoftOptOutThreshold(i interface{}) error { str, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) @@ -192,3 +201,24 @@ func validateSoftOptOutThreshold(i interface{}) error { } return nil } + +func ValidateDenoms(i interface{}) error { + v, ok := i.([]string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + // iterate over the denoms, turning them into coins and validating them + for _, denom := range v { + coin := sdktypes.Coin{ + Denom: denom, + Amount: sdktypes.NewInt(0), + } + + if err := coin.Validate(); err != nil { + return err + } + } + + return nil +} diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index cad6a58ae1..98233505d7 100644 --- a/x/ccv/consumer/types/params_test.go +++ b/x/ccv/consumer/types/params_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" ) // Tests the validation of consumer params that happens at genesis @@ -19,59 +19,63 @@ func TestValidateParams(t *testing.T) { {"default params", consumertypes.DefaultParams(), true}, { "custom valid params", - consumertypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, "0.1"), true, + consumertypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), true, }, { "custom invalid params, block per dist transmission", - consumertypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, dist transmission channel", - consumertypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, provider fee pool addr string", - consumertypes.NewParams(true, 5, "", "imabadaddress", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "imabadaddress", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, ccv timeout", - consumertypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, transfer timeout", - consumertypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, consumer redist fraction is negative", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, consumer redist fraction is over 1", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, bad consumer redist fraction ", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, negative num historical entries", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { "custom invalid params, negative unbonding period", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, "0.05"), false, + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}), false, }, { - "custom invalid params, soft opt out threshold is negative", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "-0.05"), false, + "custom invalid params, invalid soft opt out threshold", + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "-0.05", []string{"u"}, []string{}), false, }, { - "custom invalid params, soft opt out threshold is over 0.2", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.44"), false, + "custom invalid params, invalid soft opt out threshold", + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.5", []string{"u"}, []string{}), false, }, { - "custom invalid params, bad soft opt out threshold ", - consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "nickelback"), false, + "custom invalid params, invalid reward denom", + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"u"}, []string{}), false, + }, + { + "custom invalid params, invalid provider reward denom", + consumertypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{"a"}), false, }, } diff --git a/x/ccv/consumer/types/query.pb.go b/x/ccv/consumer/types/query.pb.go index d43cbf4fe8..a89562d8e1 100644 --- a/x/ccv/consumer/types/query.pb.go +++ b/x/ccv/consumer/types/query.pb.go @@ -308,40 +308,40 @@ func init() { } var fileDescriptor_f627751d3cc10225 = []byte{ - // 519 bytes of a gzipped FileDescriptorProto + // 522 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x8b, 0xd3, 0x40, 0x14, 0x6e, 0xb6, 0x3f, 0xc4, 0x59, 0xbc, 0x8c, 0x15, 0x42, 0x95, 0xb8, 0x44, 0xc1, 0xaa, 0x34, - 0x71, 0xbb, 0x87, 0x55, 0x2f, 0xca, 0xaa, 0x8b, 0x82, 0xca, 0x5a, 0xf6, 0xe4, 0x65, 0x9d, 0x4e, - 0xdf, 0xa6, 0x03, 0xcd, 0x4c, 0x76, 0x66, 0x12, 0xda, 0x9b, 0xf8, 0x07, 0x88, 0xe0, 0x7f, 0xe2, - 0xc5, 0x7f, 0x61, 0x8f, 0x0b, 0x5e, 0x3c, 0x89, 0xb4, 0xfe, 0x11, 0x1e, 0x25, 0x93, 0x64, 0x4d, - 0x41, 0xb7, 0x11, 0xbc, 0x4d, 0xbf, 0xef, 0xbd, 0xef, 0x7d, 0xf3, 0xcd, 0x6b, 0x90, 0xcf, 0xb8, - 0x06, 0x49, 0xc7, 0x84, 0xf1, 0x03, 0x05, 0x34, 0x96, 0x4c, 0xcf, 0x7c, 0x4a, 0x13, 0x9f, 0x0a, - 0xae, 0xe2, 0x10, 0xa4, 0x9f, 0x6c, 0xfa, 0x47, 0x31, 0xc8, 0x99, 0x17, 0x49, 0xa1, 0x05, 0xbe, - 0xf6, 0x87, 0x06, 0x8f, 0xd2, 0xc4, 0x2b, 0x1a, 0xbc, 0x64, 0xb3, 0xd3, 0x0e, 0x44, 0x20, 0x4c, - 0xbd, 0x9f, 0x9e, 0xb2, 0xd6, 0xce, 0x95, 0x40, 0x88, 0x60, 0x02, 0x3e, 0x89, 0x98, 0x4f, 0x38, - 0x17, 0x9a, 0x68, 0x26, 0xb8, 0xca, 0xd9, 0x7e, 0x15, 0x27, 0xa7, 0x43, 0x4c, 0x8f, 0xfb, 0x7e, - 0x0d, 0x5d, 0x7e, 0x09, 0x53, 0xbd, 0x0b, 0xf0, 0x98, 0x29, 0x2d, 0xd9, 0x30, 0x4e, 0x25, 0x9f, - 0x28, 0xcd, 0x42, 0xa2, 0x01, 0x5f, 0x47, 0x17, 0x68, 0x2c, 0x25, 0x70, 0xfd, 0x14, 0x58, 0x30, - 0xd6, 0xb6, 0xb5, 0x61, 0x75, 0xeb, 0x83, 0x65, 0x10, 0x3b, 0x08, 0x4d, 0x88, 0x2a, 0x4a, 0xd6, - 0x4c, 0x49, 0x09, 0x49, 0x79, 0x0e, 0xd3, 0x82, 0xaf, 0x67, 0xfc, 0x6f, 0x04, 0x6f, 0xa1, 0x4b, - 0xa3, 0xd2, 0xf4, 0x83, 0x43, 0x49, 0x68, 0x7a, 0xb0, 0x1b, 0x1b, 0x56, 0xf7, 0xfc, 0xa0, 0x5d, - 0x26, 0x77, 0x73, 0x0e, 0xb7, 0x51, 0x53, 0x0b, 0x4d, 0x26, 0x76, 0xd3, 0x14, 0x65, 0x3f, 0xd2, - 0x51, 0x5a, 0xec, 0x49, 0x91, 0xb0, 0x11, 0x48, 0xbb, 0x65, 0xa8, 0x12, 0x92, 0xf1, 0x8f, 0xf2, - 0x10, 0xec, 0x73, 0x05, 0x5f, 0x20, 0xee, 0x4d, 0x74, 0xe3, 0x55, 0xfa, 0x58, 0x67, 0x84, 0x32, - 0x80, 0xa3, 0x18, 0x94, 0x76, 0xdf, 0x5a, 0xa8, 0xbb, 0xba, 0x56, 0x45, 0x82, 0x2b, 0xc0, 0xfb, - 0xa8, 0x31, 0x22, 0x9a, 0x98, 0xfc, 0xd6, 0xfb, 0x0f, 0xbd, 0x0a, 0x4b, 0xe0, 0x9d, 0xa5, 0x6b, - 0xd4, 0xdc, 0x36, 0xc2, 0xc6, 0xc1, 0x1e, 0x91, 0x24, 0x54, 0x85, 0xb1, 0x37, 0xe8, 0xe2, 0x12, - 0x9a, 0x5b, 0x78, 0x86, 0x5a, 0x91, 0x41, 0x72, 0x13, 0xb7, 0x2b, 0x99, 0xc8, 0x44, 0x76, 0x1a, - 0xc7, 0xdf, 0xae, 0xd6, 0x06, 0xb9, 0x40, 0xff, 0x73, 0x1d, 0x35, 0xcd, 0x08, 0xfc, 0xd3, 0x42, - 0xf6, 0xdf, 0x42, 0xc0, 0xcf, 0x2b, 0x4d, 0xa8, 0x98, 0x77, 0xe7, 0xc5, 0x7f, 0x52, 0xcb, 0xe2, - 0x70, 0x1f, 0xbc, 0xfb, 0xf2, 0xe3, 0xe3, 0xda, 0x3d, 0xbc, 0xbd, 0xfa, 0x1f, 0x9c, 0xae, 0x6a, - 0xef, 0x10, 0xa0, 0x57, 0x5e, 0x44, 0xfc, 0xc9, 0x42, 0xeb, 0xa5, 0x9c, 0xf1, 0x76, 0x75, 0x7f, - 0x4b, 0xef, 0xd5, 0xb9, 0xfb, 0xef, 0x8d, 0xf9, 0x1d, 0xee, 0x98, 0x3b, 0xdc, 0xc2, 0xdd, 0xd5, - 0x77, 0xc8, 0x5e, 0x6e, 0x67, 0xff, 0x78, 0xee, 0x58, 0x27, 0x73, 0xc7, 0xfa, 0x3e, 0x77, 0xac, - 0x0f, 0x0b, 0xa7, 0x76, 0xb2, 0x70, 0x6a, 0x5f, 0x17, 0x4e, 0xed, 0xf5, 0xfd, 0x80, 0xe9, 0x71, - 0x3c, 0xf4, 0xa8, 0x08, 0x7d, 0x2a, 0x54, 0x28, 0x54, 0x49, 0xb4, 0x77, 0x2a, 0x3a, 0x5d, 0x96, - 0xd5, 0xb3, 0x08, 0xd4, 0xb0, 0x65, 0xbe, 0x26, 0x5b, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x1c, - 0x94, 0x9c, 0x7a, 0x0d, 0x05, 0x00, 0x00, + 0xe3, 0x76, 0x0f, 0xab, 0x07, 0x51, 0x56, 0x5d, 0x14, 0x54, 0xd6, 0x22, 0x08, 0x5e, 0xd6, 0xe9, + 0xf4, 0x6d, 0x3a, 0xd0, 0x64, 0xb2, 0x33, 0x93, 0xd0, 0xde, 0xc4, 0x3f, 0x40, 0x04, 0xff, 0x13, + 0x2f, 0xfe, 0x0b, 0x7b, 0x5c, 0xf0, 0xe2, 0x49, 0xa4, 0xf5, 0x8f, 0xf0, 0x28, 0x99, 0x24, 0x6b, + 0x0a, 0xba, 0x8d, 0xe0, 0x6d, 0xfa, 0x7d, 0xef, 0x7d, 0xef, 0x9b, 0x6f, 0x5e, 0x83, 0x08, 0x0f, + 0x35, 0x48, 0x36, 0xa6, 0x3c, 0xdc, 0x57, 0xc0, 0x62, 0xc9, 0xf5, 0x8c, 0x30, 0x96, 0x10, 0x26, + 0x42, 0x15, 0x07, 0x20, 0x49, 0xb2, 0x49, 0x0e, 0x63, 0x90, 0x33, 0x2f, 0x92, 0x42, 0x0b, 0x7c, + 0xe5, 0x0f, 0x0d, 0x1e, 0x63, 0x89, 0x57, 0x34, 0x78, 0xc9, 0x66, 0xa7, 0xed, 0x0b, 0x5f, 0x98, + 0x7a, 0x92, 0x9e, 0xb2, 0xd6, 0xce, 0x25, 0x5f, 0x08, 0x7f, 0x02, 0x84, 0x46, 0x9c, 0xd0, 0x30, + 0x14, 0x9a, 0x6a, 0x2e, 0x42, 0x95, 0xb3, 0xfd, 0x2a, 0x4e, 0x4e, 0x86, 0x98, 0x1e, 0xf7, 0xfd, + 0x1a, 0xba, 0xf8, 0x1c, 0xa6, 0x7a, 0x17, 0xe0, 0x21, 0x57, 0x5a, 0xf2, 0x61, 0x9c, 0x4a, 0x3e, + 0x52, 0x9a, 0x07, 0x54, 0x03, 0xbe, 0x8a, 0xce, 0xb1, 0x58, 0x4a, 0x08, 0xf5, 0x63, 0xe0, 0xfe, + 0x58, 0xdb, 0xd6, 0x86, 0xd5, 0xad, 0x0f, 0x96, 0x41, 0xec, 0x20, 0x34, 0xa1, 0xaa, 0x28, 0x59, + 0x33, 0x25, 0x25, 0x24, 0xe5, 0x43, 0x98, 0x16, 0x7c, 0x3d, 0xe3, 0x7f, 0x23, 0x78, 0x0b, 0x5d, + 0x18, 0x95, 0xa6, 0xef, 0x1f, 0x48, 0xca, 0xd2, 0x83, 0xdd, 0xd8, 0xb0, 0xba, 0x67, 0x07, 0xed, + 0x32, 0xb9, 0x9b, 0x73, 0xb8, 0x8d, 0x9a, 0x5a, 0x68, 0x3a, 0xb1, 0x9b, 0xa6, 0x28, 0xfb, 0x91, + 0x8e, 0xd2, 0x62, 0x4f, 0x8a, 0x84, 0x8f, 0x40, 0xda, 0x2d, 0x43, 0x95, 0x90, 0x8c, 0x7f, 0x90, + 0x87, 0x60, 0x9f, 0x29, 0xf8, 0x02, 0x71, 0xaf, 0xa3, 0x6b, 0x2f, 0xd2, 0xc7, 0x3a, 0x25, 0x94, + 0x01, 0x1c, 0xc6, 0xa0, 0xb4, 0xfb, 0xd6, 0x42, 0xdd, 0xd5, 0xb5, 0x2a, 0x12, 0xa1, 0x02, 0xfc, + 0x12, 0x35, 0x46, 0x54, 0x53, 0x93, 0xdf, 0x7a, 0xff, 0xbe, 0x57, 0x61, 0x09, 0xbc, 0xd3, 0x74, + 0x8d, 0x9a, 0xdb, 0x46, 0xd8, 0x38, 0xd8, 0xa3, 0x92, 0x06, 0xaa, 0x30, 0xf6, 0x06, 0x9d, 0x5f, + 0x42, 0x73, 0x0b, 0x4f, 0x50, 0x2b, 0x32, 0x48, 0x6e, 0xe2, 0x66, 0x25, 0x13, 0x99, 0xc8, 0x4e, + 0xe3, 0xe8, 0xdb, 0xe5, 0xda, 0x20, 0x17, 0xe8, 0x7f, 0xae, 0xa3, 0xa6, 0x19, 0x81, 0x7f, 0x5a, + 0xc8, 0xfe, 0x5b, 0x08, 0xf8, 0x69, 0xa5, 0x09, 0x15, 0xf3, 0xee, 0x3c, 0xfb, 0x4f, 0x6a, 0x59, + 0x1c, 0xee, 0xbd, 0x77, 0x5f, 0x7e, 0x7c, 0x5c, 0xbb, 0x83, 0xb7, 0x57, 0xff, 0x83, 0xd3, 0x55, + 0xed, 0x1d, 0x00, 0xf4, 0xca, 0x8b, 0x88, 0x3f, 0x59, 0x68, 0xbd, 0x94, 0x33, 0xde, 0xae, 0xee, + 0x6f, 0xe9, 0xbd, 0x3a, 0xb7, 0xff, 0xbd, 0x31, 0xbf, 0xc3, 0x2d, 0x73, 0x87, 0x1b, 0xb8, 0xbb, + 0xfa, 0x0e, 0xd9, 0xcb, 0xed, 0xbc, 0x3a, 0x9a, 0x3b, 0xd6, 0xf1, 0xdc, 0xb1, 0xbe, 0xcf, 0x1d, + 0xeb, 0xc3, 0xc2, 0xa9, 0x1d, 0x2f, 0x9c, 0xda, 0xd7, 0x85, 0x53, 0x7b, 0x7d, 0xd7, 0xe7, 0x7a, + 0x1c, 0x0f, 0x3d, 0x26, 0x02, 0xc2, 0x84, 0x0a, 0x84, 0x2a, 0x89, 0xf6, 0x4e, 0x44, 0x93, 0x3e, + 0x99, 0x2e, 0x2b, 0xeb, 0x59, 0x04, 0x6a, 0xd8, 0x32, 0x1f, 0x94, 0xad, 0x5f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xc4, 0xb4, 0x4e, 0xea, 0x10, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/ccv/consumer/types/validator.go b/x/ccv/consumer/types/validator.go index f77aeca0cd..c546a68440 100644 --- a/x/ccv/consumer/types/validator.go +++ b/x/ccv/consumer/types/validator.go @@ -1,10 +1,10 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func NewCCValidator(address []byte, power int64, pubKey cryptotypes.PubKey) (CrossChainValidator, error) { @@ -30,7 +30,7 @@ func (ccv CrossChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) func (ccv CrossChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { pk, ok := ccv.Pubkey.GetCachedValue().(cryptotypes.PubKey) if !ok { - return nil, sdkerrors.Wrapf(sdkerrorstypes.ErrInvalidType, "expecting cryptotypes.PubKey, got %T", pk) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidType, "expecting cryptotypes.PubKey, got %T", pk) } return pk, nil diff --git a/x/ccv/democracy/distribution/module.go b/x/ccv/democracy/distribution/module.go index 71a90d8dbb..3d5ca0ed74 100644 --- a/x/ccv/democracy/distribution/module.go +++ b/x/ccv/democracy/distribution/module.go @@ -13,7 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/distribution/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" abci "github.com/cometbft/cometbft/abci/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index 922fccd49f..aa1a996f12 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -11,7 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) // NewQueryCmd returns a root CLI command handler for all x/ccv/provider query commands. @@ -32,6 +32,7 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand(CmdProviderValidatorKey()) cmd.AddCommand(CmdThrottleState()) cmd.AddCommand(CmdThrottledConsumerPacketData()) + cmd.AddCommand(CmdRegisteredConsumerRewardDenoms()) return cmd } @@ -320,3 +321,38 @@ $ %s query provider throttled-consumer-packet-data foochain return cmd } + +func CmdRegisteredConsumerRewardDenoms() *cobra.Command { + cmd := &cobra.Command{ + Use: "registered-consumer-reward-denoms", + Short: "Query registered consumer reward denoms", + Long: strings.TrimSpace( + fmt.Sprintf(`Returns the registered consumer reward denoms. +Example: +$ %s query provider registered-consumer-reward-denoms +`, + version.AppName, + ), + ), + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QueryRegisteredConsumerRewardDenomsRequest{} + res, err := queryClient.QueryRegisteredConsumerRewardDenoms(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index 00f1998720..a0b9343d8a 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -2,15 +2,17 @@ package cli import ( "fmt" + "strings" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/version" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) // GetTxCmd returns the transaction commands for this module @@ -24,6 +26,7 @@ func GetTxCmd() *cobra.Command { } cmd.AddCommand(NewAssignConsumerKeyCmd()) + cmd.AddCommand(NewRegisterConsumerRewardDenomCmd()) return cmd } @@ -65,3 +68,37 @@ func NewAssignConsumerKeyCmd() *cobra.Command { return cmd } + +func NewRegisterConsumerRewardDenomCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "register-consumer-reward-denom [denom]", + Args: cobra.ExactArgs(1), + Short: "Registers a denom that can be sent from consumer chains to all validators and delegators as a reward", + Long: strings.TrimSpace( + fmt.Sprintf(`Registers a denom that can be sent from consumer chains to all validators and delegators as a reward. + +Costs a fee, which is specified in genesis.json under the "consumer_reward_denom_fee" key. Will fail if the sending account has an insufficient balance. + +Example: +$ %s tx provider register-consumer-reward-denom untrn --from mykey +`, + version.AppName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + depositorAddr := clientCtx.GetFromAddress() + + msg := types.NewMsgRegisterConsumerRewardDenom(args[0], depositorAddr) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/provider/client/proposal_handler.go b/x/ccv/provider/client/proposal_handler.go index 2e2e6b6591..6ccd855ef8 100644 --- a/x/ccv/provider/client/proposal_handler.go +++ b/x/ccv/provider/client/proposal_handler.go @@ -17,7 +17,7 @@ import ( govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" "github.com/spf13/cobra" ) @@ -57,6 +57,7 @@ Where proposal.json contains: "spawn_time": "2022-01-27T15:59:50.121607-08:00", "blocks_per_distribution_transmission": 1000, "consumer_redistribution_fraction": "0.75", + "distribution_transmission_channel": "", "historical_entries": 10000, "transfer_timeout_period": 3600000000000, "ccv_timeout_period": 2419200000000000, @@ -81,7 +82,8 @@ Where proposal.json contains: content := types.NewConsumerAdditionProposal( proposal.Title, proposal.Summary, proposal.ChainId, proposal.InitialHeight, proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, - proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, proposal.HistoricalEntries, + proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, + proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) from := clientCtx.GetFromAddress() @@ -236,6 +238,7 @@ type ConsumerAdditionProposalJSON struct { ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` + DistributionTransmissionChannel string `json:"distribution_transmission_channel"` HistoricalEntries int64 `json:"historical_entries"` CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` @@ -257,6 +260,7 @@ type ConsumerAdditionProposalReq struct { ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` + DistributionTransmissionChannel string `json:"distribution_transmission_channel"` HistoricalEntries int64 `json:"historical_entries"` CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` @@ -401,7 +405,8 @@ func postConsumerAdditionProposalHandlerFn(clientCtx client.Context) http.Handle content := types.NewConsumerAdditionProposal( req.Title, req.Description, req.ChainId, req.InitialHeight, req.GenesisHash, req.BinaryHash, req.SpawnTime, - req.ConsumerRedistributionFraction, req.BlocksPerDistributionTransmission, req.HistoricalEntries, + req.ConsumerRedistributionFraction, req.BlocksPerDistributionTransmission, + req.DistributionTransmissionChannel, req.HistoricalEntries, req.CcvTimeoutPeriod, req.TransferTimeoutPeriod, req.UnbondingPeriod) msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, req.Proposer) diff --git a/x/ccv/provider/handler.go b/x/ccv/provider/handler.go index 73759277dd..dc0c8cbc4f 100644 --- a/x/ccv/provider/handler.go +++ b/x/ccv/provider/handler.go @@ -1,11 +1,11 @@ package provider import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) func NewHandler(k *keeper.Keeper) sdk.Handler { @@ -18,8 +18,11 @@ func NewHandler(k *keeper.Keeper) sdk.Handler { case *types.MsgAssignConsumerKey: res, err := msgServer.AssignConsumerKey(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgRegisterConsumerRewardDenom: + res, err := msgServer.RegisterConsumerRewardDenom(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: - return nil, sdkerrors.Wrapf(sdkerrorstypes.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) } } } diff --git a/x/ccv/provider/handler_test.go b/x/ccv/provider/handler_test.go index 4e0828815a..0176e13b71 100644 --- a/x/ccv/provider/handler_test.go +++ b/x/ccv/provider/handler_test.go @@ -12,11 +12,11 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - testcrypto "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider" - keeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + testcrypto "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider" + keeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) func TestInvalidMsg(t *testing.T) { diff --git a/x/ccv/provider/ibc_module.go b/x/ccv/provider/ibc_module.go index bc9fc09acb..21eee84f06 100644 --- a/x/ccv/provider/ibc_module.go +++ b/x/ccv/provider/ibc_module.go @@ -3,17 +3,19 @@ package provider import ( "fmt" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // OnChanOpenInit implements the IBCModule interface @@ -30,7 +32,7 @@ func (am AppModule) OnChanOpenInit( counterparty channeltypes.Counterparty, version string, ) (string, error) { - return version, sdkerrors.Wrap(ccv.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") + return version, errorsmod.Wrap(ccv.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") } // OnChanOpenTry implements the IBCModule interface @@ -56,13 +58,13 @@ func (am AppModule) OnChanOpenTry( // ensure the counterparty port ID matches the expected consumer port ID if counterparty.PortId != ccv.ConsumerPortID { - return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, + return "", errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty port: %s, expected %s", counterparty.PortId, ccv.ConsumerPortID) } // ensure the counter party version matches the expected version if counterpartyVersion != ccv.Version { - return "", sdkerrors.Wrapf( + return "", errorsmod.Wrapf( ccv.ErrInvalidVersion, "invalid counterparty version: got: %s, expected %s", counterpartyVersion, ccv.Version) } @@ -85,12 +87,12 @@ func (am AppModule) OnChanOpenTry( // the consumer chain must be excluded from the blocked addresses // blacklist or all all ibc-transfers from the consumer chain to the // provider chain will fail - ProviderFeePoolAddr: am.keeper.GetFeeCollectorAddressStr(ctx), + ProviderFeePoolAddr: am.keeper.GetConsumerRewardsPoolAddressStr(ctx), Version: ccv.Version, } mdBz, err := (&md).Marshal() if err != nil { - return "", sdkerrors.Wrapf(ccv.ErrInvalidHandshakeMetadata, + return "", errorsmod.Wrapf(ccv.ErrInvalidHandshakeMetadata, "error marshalling ibc-try metadata: %v", err) } return string(mdBz), nil @@ -104,13 +106,13 @@ func validateCCVChannelParams( portID string, ) error { if order != channeltypes.ORDERED { - return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) + return errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) } // the port ID must match the port ID the CCV module is bounded to boundPort := keeper.GetPort(ctx) if boundPort != portID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) + return errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) } return nil } @@ -126,7 +128,7 @@ func (am AppModule) OnChanOpenAck( counterpartyChannelID string, counterpartyVersion string, ) error { - return sdkerrors.Wrap(ccv.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") + return errorsmod.Wrap(ccv.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") } // OnChanOpenConfirm implements the IBCModule interface @@ -152,7 +154,7 @@ func (am AppModule) OnChanCloseInit( channelID string, ) error { // Disallow user-initiated channel closing for provider channels - return sdkerrors.Wrap(sdkerrorstypes.ErrInvalidRequest, "user cannot close channel") + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") } // OnChanCloseConfirm implements the IBCModule interface @@ -217,7 +219,7 @@ func (am AppModule) OnAcknowledgementPacket( ) error { var ack channeltypes.Acknowledgement if err := ccv.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return sdkerrors.Wrapf(sdkerrorstypes.ErrUnknownRequest, "cannot unmarshal provider packet acknowledgement: %v", err) + return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal provider packet acknowledgement: %v", err) } if err := am.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { diff --git a/x/ccv/provider/ibc_module_test.go b/x/ccv/provider/ibc_module_test.go index acfb28b7b2..28a13dfeda 100644 --- a/x/ccv/provider/ibc_module_test.go +++ b/x/ccv/provider/ibc_module_test.go @@ -6,15 +6,18 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -24,10 +27,11 @@ import ( // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-coinit1 // Spec Tag: [CCV-PCF-COINIT.1] func TestOnChanOpenInit(t *testing.T) { + keeperParams := testkeeper.NewInMemKeeperParams(t) providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) + t, keeperParams) defer ctrl.Finish() - providerModule := provider.NewAppModule(&providerKeeper) + providerModule := provider.NewAppModule(&providerKeeper, *keeperParams.ParamsSubspace) // OnChanOpenInit must error for provider even with correct arguments _, err := providerModule.OnChanOpenInit( @@ -112,9 +116,10 @@ func TestOnChanOpenTry(t *testing.T) { for _, tc := range testCases { // Setup + keeperParams := testkeeper.NewInMemKeeperParams(t) providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) - providerModule := provider.NewAppModule(&providerKeeper) + t, keeperParams) + providerModule := provider.NewAppModule(&providerKeeper, *keeperParams.ParamsSubspace) providerKeeper.SetPort(ctx, ccv.ProviderPortID) providerKeeper.SetConsumerClientId(ctx, "consumerChainID", "clientIDToConsumer") @@ -133,7 +138,7 @@ func TestOnChanOpenTry(t *testing.T) { // Expected mock calls moduleAcct := authtypes.ModuleAccount{BaseAccount: &authtypes.BaseAccount{}} - moduleAcct.BaseAccount.Address = authtypes.NewModuleAddress(authtypes.FeeCollectorName).String() + moduleAcct.BaseAccount.Address = authtypes.NewModuleAddress(providertypes.ConsumerRewardsPool).String() // Number of calls is not asserted, since not all code paths are hit for failures gomock.InOrder( @@ -145,7 +150,7 @@ func TestOnChanOpenTry(t *testing.T) { mocks.MockClientKeeper.EXPECT().GetClientState(ctx, "clientIDToConsumer").Return( &ibctmtypes.ClientState{ChainId: "consumerChainID"}, true, ).AnyTimes(), - mocks.MockAccountKeeper.EXPECT().GetModuleAccount(ctx, authtypes.FeeCollectorName).Return(&moduleAcct).AnyTimes(), + mocks.MockAccountKeeper.EXPECT().GetModuleAccount(ctx, providertypes.ConsumerRewardsPool).Return(&moduleAcct).AnyTimes(), ) tc.mutateParams(¶ms, &providerKeeper) @@ -181,10 +186,11 @@ func TestOnChanOpenTry(t *testing.T) { // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-coack1 // Spec tag: [CCV-PCF-COACK.1] func TestOnChanOpenAck(t *testing.T) { + keeperParams := testkeeper.NewInMemKeeperParams(t) providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) + t, keeperParams) defer ctrl.Finish() - providerModule := provider.NewAppModule(&providerKeeper) + providerModule := provider.NewAppModule(&providerKeeper, *keeperParams.ParamsSubspace) // OnChanOpenAck must error for provider even with correct arguments err := providerModule.OnChanOpenAck( @@ -296,8 +302,9 @@ func TestOnChanOpenConfirm(t *testing.T) { for _, tc := range testCases { + keeperParams := testkeeper.NewInMemKeeperParams(t) providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) + t, keeperParams) gomock.InOrder(tc.mockExpectations(ctx, mocks)...) @@ -305,7 +312,7 @@ func TestOnChanOpenConfirm(t *testing.T) { providerKeeper.SetChainToChannel(ctx, "consumerChainID", "existingChannelID") } - providerModule := provider.NewAppModule(&providerKeeper) + providerModule := provider.NewAppModule(&providerKeeper, *keeperParams.ParamsSubspace) err := providerModule.OnChanOpenConfirm(ctx, "providerPortID", "channelID") diff --git a/x/ccv/provider/keeper/distribution.go b/x/ccv/provider/keeper/distribution.go index b00ec81deb..759de65147 100644 --- a/x/ccv/provider/keeper/distribution.go +++ b/x/ccv/provider/keeper/distribution.go @@ -2,9 +2,95 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) -func (k Keeper) GetFeeCollectorAddressStr(ctx sdk.Context) string { +// EndBlockRD executes EndBlock logic for the Reward Distribution sub-protocol. +// Reward Distribution follows a simple model: send tokens to the ConsumerRewardsPool, +// from where they sent to the fee collector address +func (k Keeper) EndBlockRD(ctx sdk.Context) { + // transfers all whitelisted consumer rewards to the fee collector address + k.TransferRewardsToFeeCollector(ctx) +} + +func (k Keeper) RegisterConsumerRewardDenom(ctx sdk.Context, denom string, sender sdk.AccAddress) error { + // Check if the denom is already registered + if k.ConsumerRewardDenomExists(ctx, denom) { + return consumertypes.ErrConsumerRewardDenomAlreadyRegistered + } + + // Send the consumer reward denom registration fee to the community pool + err := k.distributionKeeper.FundCommunityPool(ctx, sdk.NewCoins(k.GetConsumerRewardDenomRegistrationFee(ctx)), sender) + if err != nil { + return err + } + k.SetConsumerRewardDenom(ctx, denom) + k.Logger(ctx).Info("new consumer reward denom registered:", "denom", denom, "sender", sender.String()) + return nil +} + +func (k Keeper) GetConsumerRewardsPoolAddressStr(ctx sdk.Context) string { return k.accountKeeper.GetModuleAccount( - ctx, k.feeCollectorName).GetAddress().String() + ctx, types.ConsumerRewardsPool).GetAddress().String() +} + +func (k Keeper) SetConsumerRewardDenom( + ctx sdk.Context, + denom string, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ConsumerRewardDenomsKey(denom), []byte{}) +} + +func (k Keeper) ConsumerRewardDenomExists( + ctx sdk.Context, + denom string, +) bool { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ConsumerRewardDenomsKey(denom)) + return bz != nil +} + +func (k Keeper) GetAllConsumerRewardDenoms(ctx sdk.Context) (consumerRewardDenoms []string) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.ConsumerRewardDenomsBytePrefix}) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + key := iterator.Key()[1:] + consumerRewardDenoms = append(consumerRewardDenoms, string(key)) + } + + return consumerRewardDenoms +} + +// TransferRewardsToFeeCollector transfers all consumer rewards to the fee collector address +func (k Keeper) TransferRewardsToFeeCollector(ctx sdk.Context) { + // 1. Get the denom whitelist from the store + denoms := k.GetAllConsumerRewardDenoms(ctx) + + // 2. Iterate over the whitelist + for _, denom := range denoms { + // 3. For each denom, retrieve the balance from the consumer rewards pool + balance := k.bankKeeper.GetBalance( + ctx, + k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress(), + denom, + ) + + // if the balance is not zero, + if !balance.IsZero() { + // 4. Transfer the balance to the fee collector address + err := k.bankKeeper.SendCoinsFromModuleToModule( + ctx, + types.ConsumerRewardsPool, + k.feeCollectorName, + sdk.NewCoins(balance), + ) + if err != nil { + k.Logger(ctx).Error("cannot sent consumer rewards to fee collector:", "reward", balance.String()) + } + } + } } diff --git a/x/ccv/provider/keeper/distribution_test.go b/x/ccv/provider/keeper/distribution_test.go new file mode 100644 index 0000000000..a9aa6d88fb --- /dev/null +++ b/x/ccv/provider/keeper/distribution_test.go @@ -0,0 +1,48 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + testutil "github.com/cosmos/interchain-security/v2/testutil/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +// TestRegisterConsumerRewardDenom tests the RegisterConsumerRewardDenom method. +func TestRegisterConsumerRewardDenom(t *testing.T) { + // Setup + providerKeeper, ctx, ctrl, mocks := testutil.GetProviderKeeperAndCtx(t, testutil.NewInMemKeeperParams(t)) + defer ctrl.Finish() + defaultParams := types.DefaultParams() + providerKeeper.SetParams(ctx, defaultParams) + accAddr := sdk.AccAddress([]byte("addr1")) + gomock.InOrder( + mocks.MockDistributionKeeper.EXPECT().FundCommunityPool(ctx, + sdk.NewCoins(defaultParams.ConsumerRewardDenomRegistrationFee), accAddr).Return(nil).Times(2), + ) + + // Register a consumer reward denom, confirm it's persisted as expected + err := providerKeeper.RegisterConsumerRewardDenom(ctx, "denom1", accAddr) + require.NoError(t, err) + require.True(t, providerKeeper.ConsumerRewardDenomExists(ctx, "denom1")) + allDenoms := providerKeeper.GetAllConsumerRewardDenoms(ctx) + require.Len(t, allDenoms, 1) + require.Equal(t, "denom1", allDenoms[0]) + + // Register another consumer reward denom, confirm both denoms are persisted as expected + err = providerKeeper.RegisterConsumerRewardDenom(ctx, "denom2", accAddr) + require.NoError(t, err) + require.True(t, providerKeeper.ConsumerRewardDenomExists(ctx, "denom2")) + allDenoms = providerKeeper.GetAllConsumerRewardDenoms(ctx) + require.Len(t, allDenoms, 2) + require.Equal(t, "denom1", allDenoms[0]) + require.Equal(t, "denom2", allDenoms[1]) + + // Try to register first consumer reward denom again, confirm it fails + err = providerKeeper.RegisterConsumerRewardDenom(ctx, "denom1", accAddr) + require.Error(t, err) + require.Equal(t, consumertypes.ErrConsumerRewardDenomAlreadyRegistered, err) +} diff --git a/x/ccv/provider/keeper/genesis.go b/x/ccv/provider/keeper/genesis.go index 79e6f2052d..89845304d8 100644 --- a/x/ccv/provider/keeper/genesis.go +++ b/x/ccv/provider/keeper/genesis.go @@ -4,8 +4,8 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // InitGenesis initializes the CCV provider state and binds to PortID. @@ -73,16 +73,20 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { // Import key assignment state for _, item := range genState.ValidatorConsumerPubkeys { - k.SetValidatorConsumerPubKey(ctx, item.ChainId, *item.ProviderAddr, *item.ConsumerKey) + providerAddr := types.NewProviderConsAddress(item.ProviderAddr) + k.SetValidatorConsumerPubKey(ctx, item.ChainId, providerAddr, *item.ConsumerKey) } for _, item := range genState.ValidatorsByConsumerAddr { - k.SetValidatorByConsumerAddr(ctx, item.ChainId, *item.ConsumerAddr, *item.ProviderAddr) + consumerAddr := types.NewConsumerConsAddress(item.ConsumerAddr) + providerAddr := types.NewProviderConsAddress(item.ProviderAddr) + k.SetValidatorByConsumerAddr(ctx, item.ChainId, consumerAddr, providerAddr) } for _, item := range genState.ConsumerAddrsToPrune { for _, addr := range item.ConsumerAddrs.Addresses { - k.AppendConsumerAddrsToPrune(ctx, item.ChainId, item.VscId, *addr) + consumerAddr := types.NewConsumerConsAddress(addr) + k.AppendConsumerAddrsToPrune(ctx, item.ChainId, item.VscId, consumerAddr) } } diff --git a/x/ccv/provider/keeper/genesis_test.go b/x/ccv/provider/keeper/genesis_test.go index 0996acbc2f..5c8ee5838f 100644 --- a/x/ccv/provider/keeper/genesis_test.go +++ b/x/ccv/provider/keeper/genesis_test.go @@ -6,13 +6,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" + "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -79,22 +79,22 @@ func TestInitAndExportGenesis(t *testing.T) { []providertypes.ValidatorConsumerPubKey{ { ChainId: cChainIDs[0], - ProviderAddr: &provAddr, + ProviderAddr: provAddr.ToSdkConsAddr(), ConsumerKey: &consumerTmPubKey, }, }, []providertypes.ValidatorByConsumerAddr{ { ChainId: cChainIDs[0], - ProviderAddr: &provAddr, - ConsumerAddr: &consumerConsAddr, + ProviderAddr: provAddr.ToSdkConsAddr(), + ConsumerAddr: consumerConsAddr.ToSdkConsAddr(), }, }, []providertypes.ConsumerAddrsToPrune{ { ChainId: cChainIDs[0], VscId: vscID, - ConsumerAddrs: &providertypes.ConsumerAddressList{Addresses: []*providertypes.ConsumerConsAddress{&consumerConsAddr}}, + ConsumerAddrs: &providertypes.AddressList{Addresses: [][]byte{consumerConsAddr.ToSdkConsAddr()}}, }, }, ) @@ -155,7 +155,7 @@ func TestInitAndExportGenesis(t *testing.T) { addrs := pk.GetConsumerAddrsToPrune(ctx, cChainIDs[0], vscID) // Expect same list as what was provided in provGenesis - expectedAddrList := providertypes.ConsumerAddressList{Addresses: []*providertypes.ConsumerConsAddress{&consumerConsAddr}} + expectedAddrList := providertypes.AddressList{Addresses: [][]byte{consumerConsAddr.ToSdkConsAddr()}} require.Equal(t, expectedAddrList, addrs) // check provider chain's consumer chain states diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index bbaefbb23f..df7c28f758 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -27,7 +27,7 @@ func (k Keeper) QueryConsumerGenesis(c context.Context, req *types.QueryConsumer gen, ok := k.GetConsumerGenesis(ctx, req.ChainId) if !ok { - return nil, sdkerrors.Wrap(types.ErrUnknownConsumerChainId, req.ChainId) + return nil, errorsmod.Wrap(types.ErrUnknownConsumerChainId, req.ChainId) } return &types.QueryConsumerGenesisResponse{GenesisState: gen}, nil @@ -236,3 +236,17 @@ func (k Keeper) getSlashPacketData(ctx sdk.Context, consumerChainID string, ibcS return packet, true } + +func (k Keeper) QueryRegisteredConsumerRewardDenoms(goCtx context.Context, req *types.QueryRegisteredConsumerRewardDenomsRequest) (*types.QueryRegisteredConsumerRewardDenomsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + denoms := k.GetAllConsumerRewardDenoms(ctx) + + return &types.QueryRegisteredConsumerRewardDenomsResponse{ + Denoms: denoms, + }, nil +} diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index de295a7c41..a384edfc39 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -4,8 +4,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" sdk "github.com/cosmos/cosmos-sdk/types" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // Wrapper struct @@ -101,7 +101,7 @@ func ValidatorConsensusKeyInUse(k *Keeper, ctx sdk.Context, valAddr sdk.ValAddre inUse := false for _, validatorConsumerAddrs := range k.GetAllValidatorsByConsumerAddr(ctx, nil) { - if validatorConsumerAddrs.ConsumerAddr.ToSdkConsAddr().Equals(consensusAddr) { + if sdk.ConsAddress(validatorConsumerAddrs.ConsumerAddr).Equals(consensusAddr) { inUse = true break } @@ -120,7 +120,7 @@ func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) er func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, valConsAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for _, validatorConsumerPubKey := range h.k.GetAllValidatorConsumerPubKeys(ctx, nil) { - if validatorConsumerPubKey.ProviderAddr.ToSdkConsAddr().Equals(valConsAddr) { + if sdk.ConsAddress(validatorConsumerPubKey.ProviderAddr).Equals(valConsAddr) { consumerAddrTmp, err := ccvtypes.TMCryptoPublicKeyToConsAddr(*validatorConsumerPubKey.ConsumerKey) if err != nil { // An error here would indicate something is very wrong @@ -128,7 +128,8 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, valConsAddr sdk.ConsAddres } consumerAddr := providertypes.NewConsumerConsAddress(consumerAddrTmp) h.k.DeleteValidatorByConsumerAddr(ctx, validatorConsumerPubKey.ChainId, consumerAddr) - h.k.DeleteValidatorConsumerPubKey(ctx, validatorConsumerPubKey.ChainId, *validatorConsumerPubKey.ProviderAddr) + providerAddr := providertypes.NewProviderConsAddress(validatorConsumerPubKey.ProviderAddr) + h.k.DeleteValidatorConsumerPubKey(ctx, validatorConsumerPubKey.ChainId, providerAddr) } } diff --git a/x/ccv/provider/keeper/hooks_test.go b/x/ccv/provider/keeper/hooks_test.go index ff01e295f9..e364f61d13 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -4,9 +4,9 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" - cryptotestutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" + cryptotestutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" "github.com/golang/mock/gomock" ) diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 8d197951a8..ff14308a22 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -6,7 +6,7 @@ import ( "reflect" "time" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -20,28 +20,30 @@ import ( ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/cometbft/cometbft/libs/log" ) // Keeper defines the Cross-Chain Validation Provider Keeper type Keeper struct { - storeKey storetypes.StoreKey - cdc codec.BinaryCodec - paramSpace paramtypes.Subspace - scopedKeeper ccv.ScopedKeeper - channelKeeper ccv.ChannelKeeper - portKeeper ccv.PortKeeper - connectionKeeper ccv.ConnectionKeeper - accountKeeper ccv.AccountKeeper - clientKeeper ccv.ClientKeeper - stakingKeeper ccv.StakingKeeper - slashingKeeper ccv.SlashingKeeper - evidenceKeeper ccv.EvidenceKeeper - feeCollectorName string + storeKey storetypes.StoreKey + cdc codec.BinaryCodec + paramSpace paramtypes.Subspace + scopedKeeper ccv.ScopedKeeper + channelKeeper ccv.ChannelKeeper + portKeeper ccv.PortKeeper + connectionKeeper ccv.ConnectionKeeper + accountKeeper ccv.AccountKeeper + clientKeeper ccv.ClientKeeper + stakingKeeper ccv.StakingKeeper + slashingKeeper ccv.SlashingKeeper + evidenceKeeper ccv.EvidenceKeeper + distributionKeeper ccv.DistributionKeeper + bankKeeper ccv.BankKeeper + feeCollectorName string } // NewKeeper creates a new provider Keeper instance @@ -51,6 +53,7 @@ func NewKeeper( connectionKeeper ccv.ConnectionKeeper, clientKeeper ccv.ClientKeeper, stakingKeeper ccv.StakingKeeper, slashingKeeper ccv.SlashingKeeper, accountKeeper ccv.AccountKeeper, evidenceKeeper ccv.EvidenceKeeper, + distributionKeeper ccv.DistributionKeeper, bankKeeper ccv.BankKeeper, feeCollectorName string, ) Keeper { // set KeyTable if it has not already been set @@ -59,46 +62,56 @@ func NewKeeper( } k := Keeper{ - cdc: cdc, - storeKey: key, - paramSpace: paramSpace, - scopedKeeper: scopedKeeper, - channelKeeper: channelKeeper, - portKeeper: portKeeper, - connectionKeeper: connectionKeeper, - accountKeeper: accountKeeper, - clientKeeper: clientKeeper, - stakingKeeper: stakingKeeper, - slashingKeeper: slashingKeeper, - evidenceKeeper: evidenceKeeper, - feeCollectorName: feeCollectorName, + cdc: cdc, + storeKey: key, + paramSpace: paramSpace, + scopedKeeper: scopedKeeper, + channelKeeper: channelKeeper, + portKeeper: portKeeper, + connectionKeeper: connectionKeeper, + clientKeeper: clientKeeper, + stakingKeeper: stakingKeeper, + slashingKeeper: slashingKeeper, + accountKeeper: accountKeeper, + evidenceKeeper: evidenceKeeper, + distributionKeeper: distributionKeeper, + bankKeeper: bankKeeper, + feeCollectorName: feeCollectorName, } k.mustValidateFields() return k } +// SetParamSpace sets the param space for the provider keeper. +// Note: this is only used for testing! +func (k *Keeper) SetParamSpace(ctx sdk.Context, ps paramtypes.Subspace) { + k.paramSpace = ps +} + // Validates that the provider keeper is initialized with non-zero and // non-nil values for all its fields. Otherwise this method will panic. func (k Keeper) mustValidateFields() { // Ensures no fields are missed in this validation - if reflect.ValueOf(k).NumField() != 13 { - panic("number of fields in provider keeper is not 13") + if reflect.ValueOf(k).NumField() != 15 { + panic("number of fields in provider keeper is not 15") } - ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 1 - ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 2 - ccv.PanicIfZeroOrNil(k.paramSpace, "paramSpace") // 3 - ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 4 - ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 5 - ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 6 - ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 7 - ccv.PanicIfZeroOrNil(k.accountKeeper, "accountKeeper") // 8 - ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 9 - ccv.PanicIfZeroOrNil(k.stakingKeeper, "stakingKeeper") // 10 - ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 11 - ccv.PanicIfZeroOrNil(k.evidenceKeeper, "evidenceKeeper") // 12 - ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 13 + ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 1 + ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 2 + ccv.PanicIfZeroOrNil(k.paramSpace, "paramSpace") // 3 + ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 4 + ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 5 + ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 6 + ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 7 + ccv.PanicIfZeroOrNil(k.accountKeeper, "accountKeeper") // 8 + ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 9 + ccv.PanicIfZeroOrNil(k.stakingKeeper, "stakingKeeper") // 10 + ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 11 + ccv.PanicIfZeroOrNil(k.evidenceKeeper, "evidenceKeeper") // 12 + ccv.PanicIfZeroOrNil(k.distributionKeeper, "distributionKeeper") // 13 + ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 14 + ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 15 } // Logger returns a module-specific logger. @@ -273,7 +286,7 @@ func (k Keeper) DeleteConsumerGenesis(ctx sdk.Context, chainID string) { // is the expected consumer chain. func (k Keeper) VerifyConsumerChain(ctx sdk.Context, channelID string, connectionHops []string) error { if len(connectionHops) != 1 { - return sdkerrors.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") + return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") } connectionID := connectionHops[0] clientID, tmClient, err := k.getUnderlyingClient(ctx, connectionID) @@ -282,15 +295,15 @@ func (k Keeper) VerifyConsumerChain(ctx sdk.Context, channelID string, connectio } ccvClientId, found := k.GetConsumerClientId(ctx, tmClient.ChainId) if !found { - return sdkerrors.Wrapf(ccv.ErrClientNotFound, "cannot find client for consumer chain %s", tmClient.ChainId) + return errorsmod.Wrapf(ccv.ErrClientNotFound, "cannot find client for consumer chain %s", tmClient.ChainId) } if ccvClientId != clientID { - return sdkerrors.Wrapf(ccv.ErrInvalidConsumerClient, "CCV channel must be built on top of CCV client. expected %s, got %s", ccvClientId, clientID) + return errorsmod.Wrapf(ccv.ErrInvalidConsumerClient, "CCV channel must be built on top of CCV client. expected %s, got %s", ccvClientId, clientID) } // Verify that there isn't already a CCV channel for the consumer chain if prevChannel, ok := k.GetChainToChannel(ctx, tmClient.ChainId); ok { - return sdkerrors.Wrapf(ccv.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain %s", prevChannel, tmClient.ChainId) + return errorsmod.Wrapf(ccv.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain %s", prevChannel, tmClient.ChainId) } return nil } @@ -305,10 +318,10 @@ func (k Keeper) VerifyConsumerChain(ctx sdk.Context, channelID string, connectio func (k Keeper) SetConsumerChain(ctx sdk.Context, channelID string) error { channel, ok := k.channelKeeper.GetChannel(ctx, ccv.ProviderPortID, channelID) if !ok { - return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", channelID) + return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", channelID) } if len(channel.ConnectionHops) != 1 { - return sdkerrors.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to consumer chain") + return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to consumer chain") } connectionID := channel.ConnectionHops[0] clientID, tmClient, err := k.getUnderlyingClient(ctx, connectionID) @@ -318,7 +331,7 @@ func (k Keeper) SetConsumerChain(ctx sdk.Context, channelID string) error { // Verify that there isn't already a CCV channel for the consumer chain chainID := tmClient.ChainId if prevChannelID, ok := k.GetChainToChannel(ctx, chainID); ok { - return sdkerrors.Wrapf(ccv.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain %s", prevChannelID, chainID) + return errorsmod.Wrapf(ccv.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain %s", prevChannelID, chainID) } // the CCV channel is established: @@ -604,18 +617,18 @@ func (k Keeper) getUnderlyingClient(ctx sdk.Context, connectionID string) ( ) { conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) if !ok { - return "", nil, sdkerrors.Wrapf(conntypes.ErrConnectionNotFound, + return "", nil, errorsmod.Wrapf(conntypes.ErrConnectionNotFound, "connection not found for connection ID: %s", connectionID) } clientID = conn.ClientId clientState, ok := k.clientKeeper.GetClientState(ctx, clientID) if !ok { - return "", nil, sdkerrors.Wrapf(clienttypes.ErrClientNotFound, + return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, "client not found for client ID: %s", conn.ClientId) } tmClient, ok = clientState.(*ibctmtypes.ClientState) if !ok { - return "", nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, + return "", nil, errorsmod.Wrapf(clienttypes.ErrInvalidClientType, "invalid client type. expected %s, got %s", ibchost.Tendermint, clientState.ClientType()) } return clientID, tmClient, nil @@ -626,7 +639,7 @@ func (k Keeper) chanCloseInit(ctx sdk.Context, channelID string) error { capName := host.ChannelCapabilityPath(ccv.ProviderPortID, channelID) chanCap, ok := k.scopedKeeper.GetCapability(ctx, capName) if !ok { - return sdkerrors.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName) + return errorsmod.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName) } return k.channelKeeper.ChanCloseInit(ctx, ccv.ProviderPortID, channelID, chanCap) } @@ -1048,3 +1061,7 @@ func (k Keeper) GetSlashLog( bz := store.Get(types.SlashLogKey(providerAddr)) return bz != nil } + +func (k Keeper) BondDenom(ctx sdk.Context) string { + return k.stakingKeeper.BondDenom(ctx) +} diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 8ec7902130..db5bf98ea4 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -6,16 +6,15 @@ import ( "testing" "time" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - - ibcsimapp "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" - abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - cryptotestutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + + ibcsimapp "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" + cryptotestutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" ) diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index 1ff1ec9985..0321e089de 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -3,12 +3,12 @@ package keeper import ( "fmt" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -90,7 +90,7 @@ func (k Keeper) GetAllValidatorConsumerPubKeys(ctx sdk.Context, chainID *string) validatorConsumerPubKeys = append(validatorConsumerPubKeys, types.ValidatorConsumerPubKey{ ChainId: chainID, - ProviderAddr: &providerAddr, + ProviderAddr: providerAddr.ToSdkConsAddr(), ConsumerKey: &consumerKey, }) } @@ -116,12 +116,7 @@ func (k Keeper) GetValidatorByConsumerAddr( if bz == nil { return providerAddr, false } - err := providerAddr.Unmarshal(bz) - if err != nil { - // An error here would indicate something is very wrong, - // the provider address is assumed to be correctly serialized in SetValidatorByConsumerAddr. - panic(fmt.Sprintf("failed to unmarshal provider address: %v", err)) - } + providerAddr = types.NewProviderConsAddress(bz) return providerAddr, true } @@ -135,11 +130,7 @@ func (k Keeper) SetValidatorByConsumerAddr( ) { store := ctx.KVStore(k.storeKey) // Cons address is a type alias for a byte string, no marshaling needed - bz, err := providerAddr.Marshal() - if err != nil { - // An error here would indicate something is very wrong, - panic(fmt.Sprintf("failed to marshal provider address: %v", err)) - } + bz := providerAddr.ToSdkConsAddr() store.Set(types.ValidatorsByConsumerAddrKey(chainID, consumerAddr), bz) } @@ -173,17 +164,11 @@ func (k Keeper) GetAllValidatorsByConsumerAddr(ctx sdk.Context, chainID *string) panic(fmt.Sprintf("failed to parse chainID and consumer address: %v", err)) } consumerAddr := types.NewConsumerConsAddress(consumerAddrTmp) - var providerAddr types.ProviderConsAddress - err = providerAddr.Unmarshal(iterator.Value()) - if err != nil { - // An error here would indicate something is very wrong, - // the provider address is assumed to be correctly serialized in SetValidatorByConsumerAddr. - panic(fmt.Sprintf("failed to unmarshal provider address: %v", err)) - } + providerAddr := types.NewProviderConsAddress(iterator.Value()) validatorConsumerAddrs = append(validatorConsumerAddrs, types.ValidatorByConsumerAddr{ - ConsumerAddr: &consumerAddr, - ProviderAddr: &providerAddr, + ConsumerAddr: consumerAddr.ToSdkConsAddr(), + ProviderAddr: providerAddr.ToSdkConsAddr(), ChainId: chainID, }) } @@ -274,7 +259,7 @@ func (k Keeper) GetAllKeyAssignmentReplacements(ctx sdk.Context, chainID string) } replacements = append(replacements, types.KeyAssignmentReplacement{ - ProviderAddr: &providerAddr, + ProviderAddr: providerAddr.ToSdkConsAddr(), PrevCKey: &pubKeyAndPower.PubKey, Power: pubKeyAndPower.Power, }) @@ -302,7 +287,7 @@ func (k Keeper) DeleteKeyAssignmentReplacement(ctx sdk.Context, chainID string, func (k Keeper) AppendConsumerAddrsToPrune(ctx sdk.Context, chainID string, vscID uint64, consumerAddr types.ConsumerConsAddress) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ConsumerAddrsToPruneKey(chainID, vscID)) - var consumerAddrsToPrune types.ConsumerAddressList + var consumerAddrsToPrune types.AddressList if bz != nil { err := consumerAddrsToPrune.Unmarshal(bz) if err != nil { @@ -311,7 +296,7 @@ func (k Keeper) AppendConsumerAddrsToPrune(ctx sdk.Context, chainID string, vscI panic(err) } } - consumerAddrsToPrune.Addresses = append(consumerAddrsToPrune.Addresses, &consumerAddr) + consumerAddrsToPrune.Addresses = append(consumerAddrsToPrune.Addresses, consumerAddr.ToSdkConsAddr()) bz, err := consumerAddrsToPrune.Marshal() if err != nil { // An error here would indicate something is very wrong, @@ -327,7 +312,7 @@ func (k Keeper) GetConsumerAddrsToPrune( ctx sdk.Context, chainID string, vscID uint64, -) (consumerAddrsToPrune types.ConsumerAddressList) { +) (consumerAddrsToPrune types.AddressList) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ConsumerAddrsToPruneKey(chainID, vscID)) if bz == nil { @@ -359,7 +344,7 @@ func (k Keeper) GetAllConsumerAddrsToPrune(ctx sdk.Context, chainID string) (con // store keys are assumed to be correctly serialized in AppendConsumerAddrsToPrune. panic(err) } - var addrs types.ConsumerAddressList + var addrs types.AddressList err = addrs.Unmarshal(iterator.Value()) if err != nil { // An error here would indicate something is very wrong, @@ -409,13 +394,13 @@ func (k Keeper) AssignConsumerKey( // This ensures that a validator joining the active set who has not explicitly assigned // a consumer key, will be able to use their provider key as consumer key (as per default). if existingVal.OperatorAddress != validator.OperatorAddress { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrConsumerKeyInUse, "a different validator already uses the consumer key", ) } _, found := k.GetValidatorConsumerPubKey(ctx, chainID, providerAddr) if !found { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrCannotAssignDefaultKeyAssignment, "a validator cannot assign the default key assignment unless its key on that consumer has already been assigned", ) @@ -425,7 +410,7 @@ func (k Keeper) AssignConsumerKey( if _, found := k.GetValidatorByConsumerAddr(ctx, chainID, consumerAddr); found { // consumer key is already in use // prevent multiple validators from assigning the same key - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrConsumerKeyInUse, "a validator has assigned the consumer key already", ) } @@ -564,13 +549,14 @@ func (k Keeper) MustApplyKeyAssignmentToValUpdates( // set the old consumer key's power to 0 and the new consumer key's power to the // power in the pending key assignment. for _, replacement := range k.GetAllKeyAssignmentReplacements(ctx, chainID) { - k.DeleteKeyAssignmentReplacement(ctx, chainID, *replacement.ProviderAddr) + providerAddr := types.NewProviderConsAddress(replacement.ProviderAddr) + k.DeleteKeyAssignmentReplacement(ctx, chainID, providerAddr) newUpdates = append(newUpdates, abci.ValidatorUpdate{ PubKey: *replacement.PrevCKey, Power: 0, }) - newConsumerKey, found := k.GetValidatorConsumerPubKey(ctx, chainID, *replacement.ProviderAddr) + newConsumerKey, found := k.GetValidatorConsumerPubKey(ctx, chainID, providerAddr) if !found { // This should never happen as for every KeyAssignmentReplacement there should // be a ValidatorConsumerPubKey that was stored when AssignConsumerKey() was called. @@ -605,11 +591,12 @@ func (k Keeper) GetProviderAddrFromConsumerAddr( // as they cannot be referenced in slash requests (by a correct consumer) func (k Keeper) PruneKeyAssignments(ctx sdk.Context, chainID string, vscID uint64) { consumerAddrs := k.GetConsumerAddrsToPrune(ctx, chainID, vscID) - for _, addr := range consumerAddrs.Addresses { - k.DeleteValidatorByConsumerAddr(ctx, chainID, *addr) + for _, addrBz := range consumerAddrs.Addresses { + consumerAddr := types.NewConsumerConsAddress(addrBz) + k.DeleteValidatorByConsumerAddr(ctx, chainID, consumerAddr) k.Logger(ctx).Info("consumer address was pruned", "consumer chainID", chainID, - "consumer consensus addr", addr.String(), + "consumer consensus addr", consumerAddr.String(), ) } @@ -620,17 +607,20 @@ func (k Keeper) PruneKeyAssignments(ctx sdk.Context, chainID string, vscID uint6 func (k Keeper) DeleteKeyAssignments(ctx sdk.Context, chainID string) { // delete ValidatorConsumerPubKey for _, validatorConsumerAddr := range k.GetAllValidatorConsumerPubKeys(ctx, &chainID) { - k.DeleteValidatorConsumerPubKey(ctx, chainID, *validatorConsumerAddr.ProviderAddr) + providerAddr := types.NewProviderConsAddress(validatorConsumerAddr.ProviderAddr) + k.DeleteValidatorConsumerPubKey(ctx, chainID, providerAddr) } // delete ValidatorsByConsumerAddr for _, validatorConsumerAddr := range k.GetAllValidatorsByConsumerAddr(ctx, &chainID) { - k.DeleteValidatorByConsumerAddr(ctx, chainID, *validatorConsumerAddr.ConsumerAddr) + consumerAddr := types.NewConsumerConsAddress(validatorConsumerAddr.ConsumerAddr) + k.DeleteValidatorByConsumerAddr(ctx, chainID, consumerAddr) } // delete KeyAssignmentReplacements for _, keyAssignmentReplacement := range k.GetAllKeyAssignmentReplacements(ctx, chainID) { - k.DeleteKeyAssignmentReplacement(ctx, chainID, *keyAssignmentReplacement.ProviderAddr) + providerAddr := types.NewProviderConsAddress(keyAssignmentReplacement.ProviderAddr) + k.DeleteKeyAssignmentReplacement(ctx, chainID, providerAddr) } // delete ValidatorConsumerPubKey diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index c8b20f6076..06d2202954 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -11,13 +11,13 @@ import ( tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - cryptotestutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" + cryptotestutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" "github.com/stretchr/testify/require" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/golang/mock/gomock" ) @@ -57,7 +57,7 @@ func TestGetAllValidatorConsumerPubKey(t *testing.T) { testAssignments = append(testAssignments, types.ValidatorConsumerPubKey{ ChainId: chainIDs[rand.Intn(len(chainIDs))], - ProviderAddr: &providerAddr, + ProviderAddr: providerAddr.ToSdkConsAddr(), ConsumerKey: &consumerKey, }, ) @@ -84,11 +84,12 @@ func TestGetAllValidatorConsumerPubKey(t *testing.T) { } // sorting by ValidatorConsumerPubKey.ProviderAddr sort.Slice(expectedGetAllOneConsumerOrder, func(i, j int) bool { - return bytes.Compare(expectedGetAllOneConsumerOrder[i].ProviderAddr.ToSdkConsAddr(), expectedGetAllOneConsumerOrder[j].ProviderAddr.ToSdkConsAddr()) == -1 + return bytes.Compare(expectedGetAllOneConsumerOrder[i].ProviderAddr, expectedGetAllOneConsumerOrder[j].ProviderAddr) == -1 }) for _, assignment := range testAssignments { - pk.SetValidatorConsumerPubKey(ctx, assignment.ChainId, *assignment.ProviderAddr, *assignment.ConsumerKey) + providerAddr := types.NewProviderConsAddress(assignment.ProviderAddr) + pk.SetValidatorConsumerPubKey(ctx, assignment.ChainId, providerAddr, *assignment.ConsumerKey) } result := pk.GetAllValidatorConsumerPubKeys(ctx, &chainID) @@ -134,8 +135,8 @@ func TestGetAllValidatorsByConsumerAddr(t *testing.T) { testAssignments = append(testAssignments, types.ValidatorByConsumerAddr{ ChainId: chainIDs[rand.Intn(len(chainIDs))], - ConsumerAddr: &consumerAddr, - ProviderAddr: &providerAddr, + ConsumerAddr: consumerAddr.ToSdkConsAddr(), + ProviderAddr: providerAddr.ToSdkConsAddr(), }, ) } @@ -161,11 +162,13 @@ func TestGetAllValidatorsByConsumerAddr(t *testing.T) { } // sorting by ValidatorByConsumerAddr.ConsumerAddr sort.Slice(expectedGetAllOneConsumerOrder, func(i, j int) bool { - return bytes.Compare(expectedGetAllOneConsumerOrder[i].ConsumerAddr.ToSdkConsAddr(), expectedGetAllOneConsumerOrder[j].ConsumerAddr.ToSdkConsAddr()) == -1 + return bytes.Compare(expectedGetAllOneConsumerOrder[i].ConsumerAddr, expectedGetAllOneConsumerOrder[j].ConsumerAddr) == -1 }) for _, assignment := range testAssignments { - pk.SetValidatorByConsumerAddr(ctx, assignment.ChainId, *assignment.ConsumerAddr, *assignment.ProviderAddr) + consumerAddr := types.NewConsumerConsAddress(assignment.ConsumerAddr) + providerAddr := types.NewProviderConsAddress(assignment.ProviderAddr) + pk.SetValidatorByConsumerAddr(ctx, assignment.ChainId, consumerAddr, providerAddr) } result := pk.GetAllValidatorsByConsumerAddr(ctx, &chainID) @@ -210,7 +213,7 @@ func TestGetAllKeyAssignmentReplacements(t *testing.T) { providerAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(numAssignments + i).ProviderConsAddress() testAssignments = append(testAssignments, types.KeyAssignmentReplacement{ - ProviderAddr: &providerAddr, + ProviderAddr: providerAddr.ToSdkConsAddr(), PrevCKey: &consumerKey, Power: rand.Int63(), }, @@ -219,12 +222,14 @@ func TestGetAllKeyAssignmentReplacements(t *testing.T) { expectedGetAllOrder := testAssignments // sorting by KeyAssignmentReplacement.ProviderAddr sort.Slice(expectedGetAllOrder, func(i, j int) bool { - return bytes.Compare(expectedGetAllOrder[i].ProviderAddr.ToSdkConsAddr(), expectedGetAllOrder[j].ProviderAddr.ToSdkConsAddr()) == -1 + return bytes.Compare(expectedGetAllOrder[i].ProviderAddr, expectedGetAllOrder[j].ProviderAddr) == -1 }) - pk.SetKeyAssignmentReplacement(ctx, "consumer-2", *testAssignments[0].ProviderAddr, *testAssignments[0].PrevCKey, testAssignments[0].Power) + firstTestAssignmentProviderAddr := types.NewProviderConsAddress(testAssignments[0].ProviderAddr) + pk.SetKeyAssignmentReplacement(ctx, "consumer-2", firstTestAssignmentProviderAddr, *testAssignments[0].PrevCKey, testAssignments[0].Power) for _, assignment := range testAssignments { - pk.SetKeyAssignmentReplacement(ctx, chainID, *assignment.ProviderAddr, *assignment.PrevCKey, assignment.Power) + providerAddr := types.NewProviderConsAddress(assignment.ProviderAddr) + pk.SetKeyAssignmentReplacement(ctx, chainID, providerAddr, *assignment.PrevCKey, assignment.Power) } result := pk.GetAllKeyAssignmentReplacements(ctx, chainID) @@ -248,7 +253,7 @@ func TestConsumerAddrsToPruneCRUD(t *testing.T) { addrsToPrune = keeper.GetConsumerAddrsToPrune(ctx, chainID, vscID).Addresses require.NotEmpty(t, addrsToPrune, "addresses to prune is empty") require.Len(t, addrsToPrune, 1, "addresses to prune is not len 1") - require.Equal(t, *addrsToPrune[0], consumerAddr) + require.Equal(t, addrsToPrune[0], consumerAddr.ToSdkConsAddr().Bytes()) keeper.DeleteConsumerAddrsToPrune(ctx, chainID, vscID) addrsToPrune = keeper.GetConsumerAddrsToPrune(ctx, chainID, vscID).Addresses @@ -264,10 +269,10 @@ func TestGetAllConsumerAddrsToPrune(t *testing.T) { numAssignments := 10 testAssignments := []types.ConsumerAddrsToPrune{} for i := 0; i < numAssignments; i++ { - consumerAddresses := types.ConsumerAddressList{} + consumerAddresses := types.AddressList{} for j := 0; j < 2*(i+1); j++ { - addr := cryptotestutil.NewCryptoIdentityFromIntSeed(i * j).ConsumerConsAddress() - consumerAddresses.Addresses = append(consumerAddresses.Addresses, &addr) + addr := cryptotestutil.NewCryptoIdentityFromIntSeed(i * j).SDKValConsAddress() + consumerAddresses.Addresses = append(consumerAddresses.Addresses, addr) } testAssignments = append(testAssignments, types.ConsumerAddrsToPrune{ @@ -304,7 +309,8 @@ func TestGetAllConsumerAddrsToPrune(t *testing.T) { for _, assignment := range testAssignments { for _, addr := range assignment.ConsumerAddrs.Addresses { - pk.AppendConsumerAddrsToPrune(ctx, assignment.ChainId, assignment.VscId, *addr) + consumerAddr := types.NewConsumerConsAddress(addr) + pk.AppendConsumerAddrsToPrune(ctx, assignment.ChainId, assignment.VscId, consumerAddr) } } @@ -324,13 +330,13 @@ func checkCorrectPruningProperty(ctx sdk.Context, k providerkeeper.Keeper, chain willBePruned := map[string]bool{} for _, consAddrToPrune := range k.GetAllConsumerAddrsToPrune(ctx, chainID) { for _, cAddr := range consAddrToPrune.ConsumerAddrs.Addresses { - willBePruned[cAddr.String()] = true + willBePruned[string(cAddr)] = true } } good := true for _, valByConsAddr := range k.GetAllValidatorsByConsumerAddr(ctx, nil) { - if _, ok := willBePruned[valByConsAddr.ConsumerAddr.String()]; ok { + if _, ok := willBePruned[string(valByConsAddr.ConsumerAddr)]; ok { // Address will be pruned, everything is fine. continue } @@ -338,7 +344,7 @@ func checkCorrectPruningProperty(ctx sdk.Context, k providerkeeper.Keeper, chain isCurrentlyAssigned := false for _, valconsPubKey := range k.GetAllValidatorConsumerPubKeys(ctx, &valByConsAddr.ChainId) { consumerAddr, _ := ccvtypes.TMCryptoPublicKeyToConsAddr(*valconsPubKey.ConsumerKey) - if consumerAddr.Equals(valByConsAddr.ConsumerAddr.ToSdkConsAddr()) { + if consumerAddr.Equals(sdk.ConsAddress(valByConsAddr.ConsumerAddr)) { isCurrentlyAssigned = true break } diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index ff34bd19df..dcef272356 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -4,12 +4,13 @@ import ( "context" "encoding/base64" - sdkerrors "cosmossdk.io/errors" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) type msgServer struct { @@ -59,7 +60,7 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign // cp := ctx.ConsensusParams() // if cp != nil && cp.Validator != nil { // if !tmstrings.StringInSlice(pkType, cp.Validator.PubKeyTypes) { - // return nil, sdkerrors.Wrapf( + // return nil, errorsmod.Wrapf( // stakingtypes.ErrValidatorPubKeyTypeNotSupported, // "got: %s, expected one of: %s", pkType, cp.Validator.PubKeyTypes, // ) @@ -69,7 +70,7 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign // For now, only accept ed25519. // TODO: decide what types should be supported. if pkType != "/cosmos.crypto.ed25519.PubKey" { - return nil, sdkerrors.Wrapf( + return nil, errorsmod.Wrapf( stakingtypes.ErrValidatorPubKeyTypeNotSupported, "got: %s, expected: %s", pkType, "/cosmos.crypto.ed25519.PubKey", ) @@ -105,3 +106,24 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign return &types.MsgAssignConsumerKeyResponse{}, nil } + +func (k msgServer) RegisterConsumerRewardDenom(goCtx context.Context, msg *types.MsgRegisterConsumerRewardDenom) (*types.MsgRegisterConsumerRewardDenomResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + depositer, err := sdk.AccAddressFromBech32(msg.Depositor) + if err != nil { + return nil, err + } + + if err := k.Keeper.RegisterConsumerRewardDenom(ctx, msg.Denom, depositer); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + ccvtypes.EventTypeRegisterConsumerRewardDenom, + sdk.NewAttribute(ccvtypes.AttributeConsumerRewardDenom, msg.Denom), + sdk.NewAttribute(ccvtypes.AttributeConsumerRewardDepositor, msg.Depositor), + )) + + return &types.MsgRegisterConsumerRewardDenomResponse{}, nil +} diff --git a/x/ccv/provider/keeper/params.go b/x/ccv/provider/keeper/params.go index 8d331b9dbd..56ed85fdd4 100644 --- a/x/ccv/provider/keeper/params.go +++ b/x/ccv/provider/keeper/params.go @@ -7,8 +7,8 @@ import ( ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // GetTemplateClient returns the template client for provider proposals @@ -77,6 +77,15 @@ func (k Keeper) GetMaxThrottledPackets(ctx sdk.Context) int64 { return p } +func (k Keeper) GetConsumerRewardDenomRegistrationFee(ctx sdk.Context) sdk.Coin { + // Due to difficulties doing migrations in coordinated upgrades, this param is hardcoded to 10 ATOM in v1.1.0-multiden. + // The below code is the proper way to store the param. A future scheduled upgrade will + // need to run migrations to add the param. This will allow us to change the fee by governance. + var c sdk.Coin + k.paramSpace.Get(ctx, types.KeyConsumerRewardDenomRegistrationFee, &c) + return c +} + // GetParams returns the paramset for the provider module func (k Keeper) GetParams(ctx sdk.Context) types.Params { return types.NewParams( @@ -88,6 +97,7 @@ func (k Keeper) GetParams(ctx sdk.Context) types.Params { k.GetSlashMeterReplenishPeriod(ctx), k.GetSlashMeterReplenishFraction(ctx), k.GetMaxThrottledPackets(ctx), + k.GetConsumerRewardDenomRegistrationFee(ctx), ) } diff --git a/x/ccv/provider/keeper/params_test.go b/x/ccv/provider/keeper/params_test.go index 5fb419c923..25c368ca82 100644 --- a/x/ccv/provider/keeper/params_test.go +++ b/x/ccv/provider/keeper/params_test.go @@ -4,11 +4,13 @@ import ( "testing" "time" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" "github.com/stretchr/testify/require" ) @@ -42,6 +44,10 @@ func TestParams(t *testing.T) { time.Hour, "0.4", 100, + sdk.Coin{ + Denom: "stake", + Amount: sdk.NewInt(10000000), + }, ) providerKeeper.SetParams(ctx, newParams) params = providerKeeper.GetParams(ctx) diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index eda3c11e39..7c4a141ad8 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -7,19 +7,19 @@ import ( channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // HandleConsumerAdditionProposal will receive the consumer chain's client state from the proposal. @@ -55,7 +55,7 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, prop *types.ConsumerAdditi chainID := prop.ChainId // check that a client for this chain does not exist if _, found := k.GetConsumerClientId(ctx, chainID); found { - return sdkerrors.Wrap(ccv.ErrDuplicateConsumerChain, + return errorsmod.Wrap(ccv.ErrDuplicateConsumerChain, fmt.Sprintf("cannot create client for existent consumer chain: %s", chainID)) } @@ -154,7 +154,7 @@ func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, p *types.Consumer func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan bool) (err error) { // check that a client for chainID exists if _, found := k.GetConsumerClientId(ctx, chainID); !found { - return sdkerrors.Wrap(ccv.ErrConsumerChainNotFound, + return errorsmod.Wrap(ccv.ErrConsumerChainNotFound, fmt.Sprintf("cannot stop non-existent consumer chain: %s", chainID)) } @@ -250,14 +250,14 @@ func (k Keeper) MakeConsumerGenesis( clientState.LatestHeight = height trustPeriod, err := ccv.CalculateTrustPeriod(providerUnbondingPeriod, k.GetTrustingPeriodFraction(ctx)) if err != nil { - return gen, nil, sdkerrors.Wrapf(sdkerrorstypes.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) + return gen, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) } clientState.TrustingPeriod = trustPeriod clientState.UnbondingPeriod = providerUnbondingPeriod consState, err := k.clientKeeper.GetSelfConsensusState(ctx, height) if err != nil { - return gen, nil, sdkerrors.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) + return gen, nil, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) } var lastPowers []stakingtypes.LastValidatorPower @@ -276,7 +276,7 @@ func (k Keeper) MakeConsumerGenesis( val, found := k.stakingKeeper.GetValidator(ctx, addr) if !found { - return gen, nil, sdkerrors.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting validator from LastValidatorPowers: %s", err) + return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting validator from LastValidatorPowers: %s", err) } tmProtoPk, err := val.TmConsPublicKey() @@ -303,7 +303,7 @@ func (k Keeper) MakeConsumerGenesis( consumerGenesisParams := consumertypes.NewParams( true, prop.BlocksPerDistributionTransmission, - "", // distributionTransmissionChannel + prop.DistributionTransmissionChannel, "", // providerFeePoolAddrStr, prop.CcvTimeoutPeriod, prop.TransferTimeoutPeriod, @@ -311,6 +311,8 @@ func (k Keeper) MakeConsumerGenesis( prop.HistoricalEntries, prop.UnbondingPeriod, "0.05", + []string{}, + []string{}, ) gen = *consumertypes.NewInitialGenesisState( diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 17147d203d..922573b17c 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -17,12 +17,12 @@ import ( "github.com/stretchr/testify/require" - cryptoutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + cryptoutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // @@ -61,6 +61,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { now, // Spawn time "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -85,6 +86,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { now, "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -819,6 +821,10 @@ func TestMakeConsumerGenesis(t *testing.T) { SlashMeterReplenishPeriod: providertypes.DefaultSlashMeterReplenishPeriod, SlashMeterReplenishFraction: providertypes.DefaultSlashMeterReplenishFraction, MaxThrottledPackets: providertypes.DefaultMaxThrottledPackets, + ConsumerRewardDenomRegistrationFee: sdk.Coin{ + Denom: "stake", + Amount: sdk.NewInt(1000000), + }, } providerKeeper.SetParams(ctx, moduleParams) defer ctrl.Finish() @@ -845,7 +851,7 @@ func TestMakeConsumerGenesis(t *testing.T) { actualGenesis, _, err := providerKeeper.MakeConsumerGenesis(ctx, &prop) require.NoError(t, err) - jsonString := `{"params":{"enabled":true, "blocks_per_distribution_transmission":1000, "ccv_timeout_period":2419200000000000, "transfer_timeout_period": 3600000000000, "consumer_redistribution_fraction":"0.75", "historical_entries":10000, "unbonding_period": 1728000000000000, "soft_opt_out_threshold": "0.05"},"new_chain":true,"provider_client_state":{"chain_id":"testchain1","trust_level":{"numerator":1,"denominator":3},"trusting_period":1197504000000000,"unbonding_period":1814400000000000,"max_clock_drift":10000000000,"frozen_height":{},"latest_height":{"revision_height":5},"proof_specs":[{"leaf_spec":{"hash":1,"prehash_value":1,"length":1,"prefix":"AA=="},"inner_spec":{"child_order":[0,1],"child_size":33,"min_prefix_length":4,"max_prefix_length":12,"hash":1}},{"leaf_spec":{"hash":1,"prehash_value":1,"length":1,"prefix":"AA=="},"inner_spec":{"child_order":[0,1],"child_size":32,"min_prefix_length":1,"max_prefix_length":1,"hash":1}}],"upgrade_path":["upgrade","upgradedIBCState"],"allow_update_after_expiry":true,"allow_update_after_misbehaviour":true},"provider_consensus_state":{"timestamp":"2020-01-02T00:00:10Z","root":{"hash":"LpGpeyQVLUo9HpdsgJr12NP2eCICspcULiWa5u9udOA="},"next_validators_hash":"E30CE736441FB9101FADDAF7E578ABBE6DFDB67207112350A9A904D554E1F5BE"},"unbonding_sequences":null,"initial_val_set":[{"pub_key":{"type":"tendermint/PubKeyEd25519","value":"dcASx5/LIKZqagJWN0frOlFtcvz91frYmj/zmoZRWro="},"power":1}]}` + jsonString := `{"params":{"enabled":true, "blocks_per_distribution_transmission":1000, "ccv_timeout_period":2419200000000000, "transfer_timeout_period": 3600000000000, "consumer_redistribution_fraction":"0.75", "historical_entries":10000, "unbonding_period": 1728000000000000, "soft_opt_out_threshold": "0.05", "reward_denoms": [], "provider_reward_denoms": []},"new_chain":true,"provider_client_state":{"chain_id":"testchain1","trust_level":{"numerator":1,"denominator":3},"trusting_period":1197504000000000,"unbonding_period":1814400000000000,"max_clock_drift":10000000000,"frozen_height":{},"latest_height":{"revision_height":5},"proof_specs":[{"leaf_spec":{"hash":1,"prehash_value":1,"length":1,"prefix":"AA=="},"inner_spec":{"child_order":[0,1],"child_size":33,"min_prefix_length":4,"max_prefix_length":12,"hash":1}},{"leaf_spec":{"hash":1,"prehash_value":1,"length":1,"prefix":"AA=="},"inner_spec":{"child_order":[0,1],"child_size":32,"min_prefix_length":1,"max_prefix_length":1,"hash":1}}],"upgrade_path":["upgrade","upgradedIBCState"],"allow_update_after_expiry":true,"allow_update_after_misbehaviour":true},"provider_consensus_state":{"timestamp":"2020-01-02T00:00:10Z","root":{"hash":"LpGpeyQVLUo9HpdsgJr12NP2eCICspcULiWa5u9udOA="},"next_validators_hash":"E30CE736441FB9101FADDAF7E578ABBE6DFDB67207112350A9A904D554E1F5BE"},"unbonding_sequences":null,"initial_val_set":[{"pub_key":{"type":"tendermint/PubKeyEd25519","value":"dcASx5/LIKZqagJWN0frOlFtcvz91frYmj/zmoZRWro="},"power":1}]}` var expectedGenesis consumertypes.GenesisState err = json.Unmarshal([]byte(jsonString), &expectedGenesis) @@ -879,6 +885,7 @@ func TestBeginBlockInit(t *testing.T) { now.Add(-time.Hour*2).UTC(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -889,6 +896,7 @@ func TestBeginBlockInit(t *testing.T) { now.Add(-time.Hour*1).UTC(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -899,6 +907,7 @@ func TestBeginBlockInit(t *testing.T) { now.Add(time.Hour).UTC(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -909,6 +918,7 @@ func TestBeginBlockInit(t *testing.T) { now.UTC(), "0.75", 10, + "", 10000, 100000000000, 100000000000, diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index 44a5f12c26..fed6f1f8ce 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -4,14 +4,15 @@ import ( "fmt" "strconv" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // OnRecvVSCMaturedPacket handles a VSCMatured packet @@ -53,14 +54,25 @@ func (k Keeper) OnRecvVSCMaturedPacket( // the "VSC Maturity and Slashing Order" CCV property. If VSC matured packet data DOES NOT // trail slash packet data for that consumer, it will be handled in this method, // bypassing HandleThrottleQueues. -func (k Keeper) HandleLeadingVSCMaturedPackets(ctx sdk.Context) { +func (k Keeper) HandleLeadingVSCMaturedPackets(ctx sdk.Context) (vscMaturedHandledThisBlock int) { + vscMaturedHandledThisBlock = 0 for _, chain := range k.GetAllConsumerChains(ctx) { + // Note: it's assumed the order of the vsc matured slice matches the order of the ibc seq nums slice, + // in that a vsc matured packet data at index i is associated with the ibc seq num at index i. leadingVscMatured, ibcSeqNums := k.GetLeadingVSCMaturedData(ctx, chain.ChainId) - for _, data := range leadingVscMatured { + ibcSeqNumsHandled := []uint64{} + for idx, data := range leadingVscMatured { + if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { + // Break from inner for-loop, DeleteThrottledPacketData will still be called for this consumer + break + } k.HandleVSCMaturedPacket(ctx, chain.ChainId, data) + vscMaturedHandledThisBlock++ + ibcSeqNumsHandled = append(ibcSeqNumsHandled, ibcSeqNums[idx]) } - k.DeleteThrottledPacketData(ctx, chain.ChainId, ibcSeqNums...) + k.DeleteThrottledPacketData(ctx, chain.ChainId, ibcSeqNumsHandled...) } + return vscMaturedHandledThisBlock } // HandleVSCMaturedPacket handles a VSCMatured packet. @@ -135,7 +147,7 @@ func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Pac // stop consumer chain and release unbonding return k.StopConsumerChain(ctx, chainID, false) } - return sdkerrors.Wrapf(providertypes.ErrUnknownConsumerChannelId, "recv ErrorAcknowledgement on unknown channel %s", packet.SourceChannel) + return errorsmod.Wrapf(providertypes.ErrUnknownConsumerChannelId, "recv ErrorAcknowledgement on unknown channel %s", packet.SourceChannel) } return nil } @@ -147,7 +159,7 @@ func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet) err if !found { k.Logger(ctx).Error("packet timeout, unknown channel:", "channelID", packet.SourceChannel) // abort transaction - return sdkerrors.Wrap( + return errorsmod.Wrap( channeltypes.ErrInvalidChannelState, packet.SourceChannel, ) @@ -204,12 +216,17 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, chainID, channelID string // IBC client is expired! // leave the packet data stored to be sent once the client is upgraded // the client cannot expire during iteration (in the middle of a block) - k.Logger(ctx).Debug("IBC client is expired, cannot send VSC, leaving packet data stored:", "chainID", chainID, "vscid", data.ValsetUpdateId) + k.Logger(ctx).Info("IBC client is expired, cannot send VSC, leaving packet data stored:", "chainID", chainID, "vscid", data.ValsetUpdateId) return } - // TODO do not panic if the send fails - // https://github.com/cosmos/interchain-security/issues/649 - panic(fmt.Errorf("packet could not be sent over IBC: %w", err)) + // Not able to send packet over IBC! + k.Logger(ctx).Error("cannot send VSC, removing consumer:", "chainID", chainID, "vscid", data.ValsetUpdateId, "err", err.Error()) + // If this happens, most likely the consumer is malicious; remove it + err := k.StopConsumerChain(ctx, chainID, true) + if err != nil { + panic(fmt.Errorf("consumer chain failed to stop: %w", err)) + } + return } // set the VSC send timestamp for this packet; // note that the VSC send timestamp are set when the packets @@ -272,13 +289,14 @@ func (k Keeper) EndBlockCIS(ctx sdk.Context) { // - Marshaling and/or store corruption errors. // - Setting invalid slash meter values (see SetSlashMeter). k.CheckForSlashMeterReplenishment(ctx) + // Handle leading vsc matured packets before throttling logic. // // Note: HandleLeadingVSCMaturedPackets contains panics for the following scenarios, any of which should never occur // if the protocol is correct and external data is properly validated: // // - Marshaling and/or store corruption errors. - k.HandleLeadingVSCMaturedPackets(ctx) + vscMaturedHandledThisBlock := k.HandleLeadingVSCMaturedPackets(ctx) // Handle queue entries considering throttling logic. // // Note: HandleThrottleQueues contains panics for the following scenarios, any of which should never occur @@ -287,7 +305,7 @@ func (k Keeper) EndBlockCIS(ctx sdk.Context) { // - SlashMeter has not been set (which should be set in InitGenesis, see InitializeSlashMeter). // - Marshaling and/or store corruption errors. // - Setting invalid slash meter values (see SetSlashMeter). - k.HandleThrottleQueues(ctx) + k.HandleThrottleQueues(ctx, vscMaturedHandledThisBlock) } // OnRecvSlashPacket delivers a received slash packet, validates it and diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index d5c6cb4f6d..07e967ae41 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -11,12 +11,13 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" exported "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibcsimapp "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" - cryptotestutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + ibcsimapp "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" + cryptotestutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -676,3 +677,40 @@ func TestHandleVSCMaturedPacket(t *testing.T) { _, found = pk.GetUnbondingOpIndex(ctx, "chain-1", 3) require.False(t, found) } + +// TestSendVSCPacketsToChainFailure tests the SendVSCPacketsToChain method failing +func TestSendVSCPacketsToChainFailure(t *testing.T) { + // Keeper setup + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + providerKeeper.SetParams(ctx, providertypes.DefaultParams()) + + // Append mocks for full consumer setup + mockCalls := testkeeper.GetMocksForSetConsumerChain(ctx, &mocks, "consumerChainID") + + // Set 3 pending vsc packets + providerKeeper.AppendPendingVSCPackets(ctx, "consumerChainID", []ccv.ValidatorSetChangePacketData{{}, {}, {}}...) + + // append mocks for the channel keeper to return an error + mockCalls = append(mockCalls, + mocks.MockChannelKeeper.EXPECT().GetChannel(ctx, ccv.ProviderPortID, + "CCVChannelID").Return(channeltypes.Channel{}, false).Times(1), + ) + + // Append mocks for expected call to StopConsumerChain + mockCalls = append(mockCalls, testkeeper.GetMocksForStopConsumerChain(ctx, &mocks)...) + + // Assert mock calls hit + gomock.InOrder(mockCalls...) + + // Execute setup + err := providerKeeper.SetConsumerChain(ctx, "channelID") + require.NoError(t, err) + providerKeeper.SetConsumerClientId(ctx, "consumerChainID", "clientID") + + // No panic should occur, StopConsumerChain should be called + providerKeeper.SendVSCPacketsToChain(ctx, "consumerChainID", "CCVChannelID") + + // Pending VSC packets should be deleted in StopConsumerChain + require.Empty(t, providerKeeper.GetPendingVSCPackets(ctx, "consumerChainID")) +} diff --git a/x/ccv/provider/keeper/throttle.go b/x/ccv/provider/keeper/throttle.go index 4cfcc48a99..d08f7bf5e0 100644 --- a/x/ccv/provider/keeper/throttle.go +++ b/x/ccv/provider/keeper/throttle.go @@ -7,22 +7,32 @@ import ( "cosmossdk.io/math" tmtypes "github.com/cometbft/cometbft/types" sdktypes "github.com/cosmos/cosmos-sdk/types" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // This file contains functionality relevant to the throttling of slash and vsc matured packets, aka circuit breaker logic. +const vscMaturedHandledPerBlockLimit = 100 + // HandleThrottleQueues iterates over the global slash entry queue, and // handles all or some portion of throttled (slash and/or VSC matured) packet data received from // consumer chains. The slash meter is decremented appropriately in this method. -func (k Keeper) HandleThrottleQueues(ctx sdktypes.Context) { +func (k Keeper) HandleThrottleQueues(ctx sdktypes.Context, vscMaturedHandledThisBlock int) { meter := k.GetSlashMeter(ctx) // Return if meter is negative in value if meter.IsNegative() { return } + // Return if vsc matured handle limit was already reached this block, during HandleLeadingVSCMaturedPackets. + // It makes no practical difference for throttling logic to execute next block. + // By doing this, we assure that all leading vsc matured packets were handled before any slash packets. + if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { + return + } + // Obtain all global slash entries, where only some of them may be handled in this method, // depending on the value of the slash meter. allEntries := k.GetAllGlobalSlashEntries(ctx) @@ -30,12 +40,13 @@ func (k Keeper) HandleThrottleQueues(ctx sdktypes.Context) { for _, globalEntry := range allEntries { // Subtract voting power that will be jailed/tombstoned from the slash meter - meter = meter.Sub(k.GetEffectiveValPower(ctx, *globalEntry.ProviderValConsAddr)) + providerAddr := providertypes.NewProviderConsAddress(globalEntry.ProviderValConsAddr) + meter = meter.Sub(k.GetEffectiveValPower(ctx, providerAddr)) // Handle one slash and any trailing vsc matured packet data instances by passing in // chainID and appropriate callbacks, relevant packet data is deleted in this method. - k.HandlePacketDataForChain(ctx, globalEntry.ConsumerChainID, k.HandleSlashPacket, k.HandleVSCMaturedPacket) + k.HandlePacketDataForChain(ctx, globalEntry.ConsumerChainID, k.HandleSlashPacket, k.HandleVSCMaturedPacket, vscMaturedHandledThisBlock) handledEntries = append(handledEntries, globalEntry) // don't handle any more global entries if meter becomes negative in value @@ -82,18 +93,31 @@ func (k Keeper) GetEffectiveValPower(ctx sdktypes.Context, func (k Keeper) HandlePacketDataForChain(ctx sdktypes.Context, consumerChainID string, slashPacketHandler func(sdktypes.Context, string, ccvtypes.SlashPacketData), vscMaturedPacketHandler func(sdktypes.Context, string, ccvtypes.VSCMaturedPacketData), + vscMaturedHandledThisBlock int, ) { // Get slash packet data and trailing vsc matured packet data, handle it all. slashFound, slashData, vscMaturedData, seqNums := k.GetSlashAndTrailingData(ctx, consumerChainID) + seqNumsHandled := []uint64{} if slashFound { slashPacketHandler(ctx, consumerChainID, slashData) + // Due to HandleLeadingVSCMaturedPackets() running before HandleThrottleQueues(), and the fact that + // HandleThrottleQueues() will return until all leading vsc matured have been handled, a slash packet + // should always be the first packet in the queue. So we can safely append the first seqNum here. + seqNumsHandled = append(seqNumsHandled, seqNums[0]) } - for _, vscMData := range vscMaturedData { + for idx, vscMData := range vscMaturedData { + if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { + // Break from for-loop, DeleteThrottledPacketData will still be called for this consumer + break + } vscMaturedPacketHandler(ctx, consumerChainID, vscMData) + vscMaturedHandledThisBlock++ + // Append seq num for this vsc matured packet + seqNumsHandled = append(seqNumsHandled, seqNums[idx+1]) // Note idx+1, since slash packet is at index 0 } // Delete handled data after it has all been handled. - k.DeleteThrottledPacketData(ctx, consumerChainID, seqNums...) + k.DeleteThrottledPacketData(ctx, consumerChainID, seqNumsHandled...) } // InitializeSlashMeter initializes the slash meter to it's max value (also its allowance), @@ -191,11 +215,7 @@ func (k Keeper) GetSlashMeterAllowance(ctx sdktypes.Context) math.Int { func (k Keeper) QueueGlobalSlashEntry(ctx sdktypes.Context, entry providertypes.GlobalSlashEntry) { store := ctx.KVStore(k.storeKey) key := providertypes.GlobalSlashEntryKey(entry) - bz, err := entry.ProviderValConsAddr.Marshal() - if err != nil { - // This should never happen, since the provider val cons addr should be a valid sdk address - panic(fmt.Sprintf("failed to marshal validator consensus address: %s", err.Error())) - } + bz := entry.ProviderValConsAddr store.Set(key, bz) } @@ -229,12 +249,7 @@ func (k Keeper) GetAllGlobalSlashEntries(ctx sdktypes.Context) []providertypes.G // MustParseGlobalSlashEntryKey should not panic, since we should be iterating over keys that're // assumed to be correctly serialized in QueueGlobalSlashEntry. recvTime, chainID, ibcSeqNum := providertypes.MustParseGlobalSlashEntryKey(iterator.Key()) - valAddr := providertypes.ProviderConsAddress{} - err := valAddr.Unmarshal(iterator.Value()) - if err != nil { - // This should never happen, provider cons address is assumed to be correctly serialized in QueueGlobalSlashEntry - panic(fmt.Sprintf("failed to unmarshal validator consensus address: %s", err.Error())) - } + valAddr := providertypes.NewProviderConsAddress(iterator.Value()) entry := providertypes.NewGlobalSlashEntry(recvTime, chainID, ibcSeqNum, valAddr) entries = append(entries, entry) } diff --git a/x/ccv/provider/keeper/throttle_test.go b/x/ccv/provider/keeper/throttle_test.go index a18e1c9f10..86a0ee1415 100644 --- a/x/ccv/provider/keeper/throttle_test.go +++ b/x/ccv/provider/keeper/throttle_test.go @@ -6,17 +6,19 @@ import ( "time" "cosmossdk.io/math" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" - "github.com/golang/mock/gomock" tmtypes "github.com/cometbft/cometbft/types" sdktypes "github.com/cosmos/cosmos-sdk/types" - cryptoutil "github.com/cosmos/interchain-security/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" + + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" + + cryptoutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) // TestHandlePacketDataForChain tests the HandlePacketDataForChain function. Note: Only one consumer is tested here, @@ -135,7 +137,7 @@ func TestHandlePacketDataForChain(t *testing.T) { handledData = append(handledData, data) } - providerKeeper.HandlePacketDataForChain(ctx, tc.chainID, slashHandleCounter, vscMaturedHandleCounter) + providerKeeper.HandlePacketDataForChain(ctx, tc.chainID, slashHandleCounter, vscMaturedHandleCounter, 0) // Assert number of handled data instances matches expected number require.Equal(t, len(tc.expectedHandledIndexes), len(handledData)) diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index 4615344446..ca83c9011b 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -12,10 +12,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - "github.com/cosmos/interchain-security/x/ccv/provider/client/cli" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/client/cli" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" ) @@ -82,13 +86,15 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic - keeper *keeper.Keeper + keeper *keeper.Keeper + paramSpace paramtypes.Subspace } // NewAppModule creates a new provider module -func NewAppModule(k *keeper.Keeper) AppModule { +func NewAppModule(k *keeper.Keeper, paramSpace paramtypes.Subspace) AppModule { return AppModule{ - keeper: k, + keeper: k, + paramSpace: paramSpace, } } @@ -123,7 +129,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { @@ -142,6 +148,8 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V am.keeper.EndBlockCCR(ctx) // EndBlock logic needed for the Validator Set Update sub-protocol am.keeper.EndBlockVSU(ctx) + // EndBlock logic need for the Reward Distribution sub-protocol + am.keeper.EndBlockRD(ctx) return []abci.ValidatorUpdate{} } diff --git a/x/ccv/provider/module_test.go b/x/ccv/provider/module_test.go index 9834741b92..2cb08d0daf 100644 --- a/x/ccv/provider/module_test.go +++ b/x/ccv/provider/module_test.go @@ -5,11 +5,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -94,7 +96,7 @@ func TestInitGenesis(t *testing.T) { keeperParams := testkeeper.NewInMemKeeperParams(t) providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) - appModule := provider.NewAppModule(&providerKeeper) + appModule := provider.NewAppModule(&providerKeeper, *keeperParams.ParamsSubspace) genState := types.NewGenesisState( providerKeeper.GetValidatorSetUpdateId(ctx), nil, diff --git a/x/ccv/provider/proposal_handler.go b/x/ccv/provider/proposal_handler.go index 13de8bb9df..2bfb71c73b 100644 --- a/x/ccv/provider/proposal_handler.go +++ b/x/ccv/provider/proposal_handler.go @@ -1,12 +1,13 @@ package provider import ( - sdkerrors "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrorstypes "github.com/cosmos/cosmos-sdk/types/errors" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/interchain-security/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) // NewProviderProposalHandler defines the handler for consumer addition, @@ -22,7 +23,7 @@ func NewProviderProposalHandler(k keeper.Keeper) govv1beta1.Handler { case *types.EquivocationProposal: return k.HandleEquivocationProposal(ctx, c) default: - return sdkerrors.Wrapf(sdkerrorstypes.ErrUnknownRequest, "unrecognized ccv proposal content type: %T", c) + return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ccv proposal content type: %T", c) } } } diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index dc2abaaf01..35b7821dd7 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -13,9 +13,10 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - testkeeper "github.com/cosmos/interchain-security/testutil/keeper" - "github.com/cosmos/interchain-security/x/ccv/provider" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + + testkeeper "github.com/cosmos/interchain-security/v2/testutil/keeper" + "github.com/cosmos/interchain-security/v2/x/ccv/provider" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) // TestProviderProposalHandler tests the highest level handler for proposals @@ -41,6 +42,7 @@ func TestProviderProposalHandler(t *testing.T) { clienttypes.NewHeight(2, 3), []byte("gen_hash"), []byte("bin_hash"), now, "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -58,14 +60,14 @@ func TestProviderProposalHandler(t *testing.T) { }, { // no slash log for equivocation - name: "invalid equivocation posal", + name: "invalid equivocation proposal", content: providertypes.NewEquivocationProposal( "title", "description", []*evidencetypes.Equivocation{equivocation}), blockTime: hourFromNow, expValidEquivocation: false, }, { - name: "valid equivocation posal", + name: "valid equivocation proposal", content: providertypes.NewEquivocationProposal( "title", "description", []*evidencetypes.Equivocation{equivocation}), blockTime: hourFromNow, diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index 48946650d2..54c29442ae 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -27,10 +27,15 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*sdk.Msg)(nil), &MsgAssignConsumerKey{}, ) + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgRegisterConsumerRewardDenom{}, + ) registry.RegisterImplementations( (*govv1beta1.Content)(nil), &EquivocationProposal{}, ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/ccv/provider/types/consumer.go b/x/ccv/provider/types/consumer.go index de2d4cb4bf..29098b4521 100644 --- a/x/ccv/provider/types/consumer.go +++ b/x/ccv/provider/types/consumer.go @@ -1,8 +1,8 @@ package types import ( - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) func NewConsumerStates( diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 1d0cfe9013..12fbfbe9c2 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -1,22 +1,24 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" ) // Provider sentinel errors var ( - ErrInvalidConsumerAdditionProposal = sdkerrors.Register(ModuleName, 1, "invalid consumer addition proposal") - ErrInvalidConsumerRemovalProp = sdkerrors.Register(ModuleName, 2, "invalid consumer removal proposal") - ErrUnknownConsumerChainId = sdkerrors.Register(ModuleName, 3, "no consumer chain with this chain id") - ErrUnknownConsumerChannelId = sdkerrors.Register(ModuleName, 4, "no consumer chain with this channel id") - ErrInvalidConsumerConsensusPubKey = sdkerrors.Register(ModuleName, 5, "empty consumer consensus public key") - ErrBlankConsumerChainID = sdkerrors.Register(ModuleName, 6, "consumer chain id must not be blank") - ErrConsumerKeyNotFound = sdkerrors.Register(ModuleName, 7, "consumer key not found") - ErrNoValidatorConsumerAddress = sdkerrors.Register(ModuleName, 8, "error getting validator consumer address") - ErrNoValidatorProviderAddress = sdkerrors.Register(ModuleName, 9, "error getting validator provider address") - ErrConsumerKeyInUse = sdkerrors.Register(ModuleName, 10, "consumer key is already in use by a validator") - ErrCannotAssignDefaultKeyAssignment = sdkerrors.Register(ModuleName, 11, "cannot re-assign default key assignment") - ErrInvalidConsumerParams = sdkerrors.Register(ModuleName, 12, "invalid consumer params") - ErrInvalidProviderAddress = sdkerrors.Register(ModuleName, 13, "invalid provider address") + ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal") + ErrInvalidConsumerRemovalProp = errorsmod.Register(ModuleName, 2, "invalid consumer removal proposal") + ErrUnknownConsumerChainId = errorsmod.Register(ModuleName, 3, "no consumer chain with this chain id") + ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id") + ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key") + ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 6, "consumer chain id must not be blank") + ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found") + ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address") + ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address") + ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator") + ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment") + ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params") + ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address") + ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom") + ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address") ) diff --git a/x/ccv/provider/types/genesis.go b/x/ccv/provider/types/genesis.go index f863e81bb7..4508fd6eb6 100644 --- a/x/ccv/provider/types/genesis.go +++ b/x/ccv/provider/types/genesis.go @@ -3,10 +3,11 @@ package types import ( "fmt" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" ) func NewGenesisState( @@ -47,7 +48,7 @@ func DefaultGenesisState() *GenesisState { func (gs GenesisState) Validate() error { if gs.ValsetUpdateId == 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "valset update ID cannot be equal to zero") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "valset update ID cannot be equal to zero") } for _, ubdOp := range gs.UnbondingOps { @@ -58,26 +59,26 @@ func (gs GenesisState) Validate() error { for _, prop := range gs.ConsumerAdditionProposals { if err := prop.ValidateBasic(); err != nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, err.Error()) + return errorsmod.Wrap(ccv.ErrInvalidGenesis, err.Error()) } } for _, prop := range gs.ConsumerRemovalProposals { if err := prop.ValidateBasic(); err != nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, err.Error()) + return errorsmod.Wrap(ccv.ErrInvalidGenesis, err.Error()) } } if len(gs.ValsetUpdateIdToHeight) > 0 { // check only the first tuple of the list since it is ordered by VSC ID if gs.ValsetUpdateIdToHeight[0].ValsetUpdateId == 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "valset update ID cannot be equal to zero") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "valset update ID cannot be equal to zero") } } for _, cs := range gs.ConsumerStates { if err := cs.Validate(); err != nil { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, fmt.Sprintf("%s: for consumer chain id: %s", err, cs.ChainId)) + return errorsmod.Wrap(ccv.ErrInvalidGenesis, fmt.Sprintf("%s: for consumer chain id: %s", err, cs.ChainId)) } } @@ -97,7 +98,7 @@ func (gs GenesisState) Validate() error { func (gs GenesisState) ValidateUnbondingOp(ubdOp UnbondingOp) error { if len(ubdOp.UnbondingConsumerChains) == 0 { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "unbonding operations cannot have an empty consumer chain list") + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "unbonding operations cannot have an empty consumer chain list") } // Check that the ID is set correctly in the UnbondingOpsIndex @@ -119,7 +120,7 @@ func (gs GenesisState) ValidateUnbondingOp(ubdOp UnbondingOp) error { } } if !found { - return sdkerrors.Wrap(ccv.ErrInvalidGenesis, + return errorsmod.Wrap(ccv.ErrInvalidGenesis, fmt.Sprintf("unbonding operation without UnbondingOpsIndex, opID=%d, chainID=%s", ubdOp.Id, chainID)) } } diff --git a/x/ccv/provider/types/genesis.pb.go b/x/ccv/provider/types/genesis.pb.go index 5fd2f6e98a..84110c9b96 100644 --- a/x/ccv/provider/types/genesis.pb.go +++ b/x/ccv/provider/types/genesis.pb.go @@ -8,8 +8,8 @@ import ( _ "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" - types1 "github.com/cosmos/interchain-security/x/ccv/consumer/types" - types "github.com/cosmos/interchain-security/x/ccv/types" + types1 "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + types "github.com/cosmos/interchain-security/v2/x/ccv/types" io "io" math "math" math_bits "math/bits" @@ -173,10 +173,12 @@ type ConsumerState struct { InitialHeight uint64 `protobuf:"varint,4,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height,omitempty"` // ConsumerGenesis defines the initial consumer chain genesis states ConsumerGenesis types1.GenesisState `protobuf:"bytes,5,opt,name=consumer_genesis,json=consumerGenesis,proto3" json:"consumer_genesis"` - // PendingValsetChanges defines the pending validator set changes for the consumer chain + // PendingValsetChanges defines the pending validator set changes for the + // consumer chain PendingValsetChanges []types.ValidatorSetChangePacketData `protobuf:"bytes,6,rep,name=pending_valset_changes,json=pendingValsetChanges,proto3" json:"pending_valset_changes"` SlashDowntimeAck []string `protobuf:"bytes,7,rep,name=slash_downtime_ack,json=slashDowntimeAck,proto3" json:"slash_downtime_ack,omitempty"` - // UnbondingOpsIndex defines the unbonding operations waiting on this consumer chain + // UnbondingOpsIndex defines the unbonding operations waiting on this consumer + // chain UnbondingOpsIndex []VscUnbondingOps `protobuf:"bytes,8,rep,name=unbonding_ops_index,json=unbondingOpsIndex,proto3" json:"unbonding_ops_index"` } @@ -334,61 +336,61 @@ func init() { } var fileDescriptor_48411d9c7900d48e = []byte{ - // 853 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x41, 0x8f, 0xdb, 0x44, + // 856 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0xdb, 0x44, 0x14, 0x5e, 0xef, 0xa6, 0xdb, 0xcd, 0x6c, 0x77, 0x59, 0x86, 0x55, 0x70, 0xb3, 0x90, 0xae, 0x02, - 0x48, 0x91, 0x00, 0x1b, 0x07, 0x0e, 0x50, 0xe0, 0xd0, 0xb4, 0x12, 0x44, 0x08, 0x11, 0xa5, 0xdb, - 0x1e, 0xca, 0xc1, 0x9a, 0x8c, 0x47, 0xc9, 0x10, 0x7b, 0xc6, 0x9a, 0x19, 0x9b, 0x5a, 0x08, 0x89, - 0x8a, 0x3f, 0xc0, 0xbf, 0xa2, 0xc7, 0x1e, 0x39, 0x55, 0x68, 0xf7, 0x1f, 0xf0, 0x0b, 0x90, 0xc7, - 0x63, 0xd7, 0x5e, 0x12, 0x48, 0xb8, 0xc5, 0xef, 0x9b, 0xf7, 0x7d, 0xef, 0xcd, 0x9b, 0xf9, 0x26, - 0xc0, 0xa3, 0x4c, 0x11, 0x81, 0x17, 0x88, 0x32, 0x5f, 0x12, 0x9c, 0x08, 0xaa, 0x32, 0x17, 0xe3, - 0xd4, 0x8d, 0x05, 0x4f, 0x69, 0x40, 0x84, 0x9b, 0x7a, 0xee, 0x9c, 0x30, 0x22, 0xa9, 0x74, 0x62, - 0xc1, 0x15, 0x87, 0xef, 0xac, 0x48, 0x71, 0x30, 0x4e, 0x9d, 0x32, 0xc5, 0x49, 0xbd, 0xee, 0xe9, - 0x9c, 0xcf, 0xb9, 0x5e, 0xef, 0xe6, 0xbf, 0x8a, 0xd4, 0xee, 0xbb, 0xeb, 0xd4, 0x52, 0xcf, 0x35, - 0x0c, 0x8a, 0x77, 0x87, 0x9b, 0xd4, 0x54, 0x89, 0xfd, 0x47, 0x0e, 0xe6, 0x4c, 0x26, 0x51, 0x91, - 0x53, 0xfe, 0x36, 0x39, 0xde, 0x26, 0x39, 0x8d, 0xde, 0xbb, 0x6f, 0x29, 0xc2, 0x02, 0x22, 0x22, - 0xca, 0x94, 0x8b, 0x45, 0x16, 0x2b, 0xee, 0x2e, 0x49, 0x66, 0xd0, 0xfe, 0xef, 0x6d, 0x70, 0xeb, - 0xab, 0x62, 0xfd, 0x43, 0x85, 0x14, 0x81, 0x03, 0x70, 0x92, 0xa2, 0x50, 0x12, 0xe5, 0x27, 0x71, - 0x80, 0x14, 0xf1, 0x69, 0x60, 0x5b, 0xe7, 0xd6, 0xa0, 0x35, 0x3d, 0x2e, 0xe2, 0x8f, 0x74, 0x78, - 0x1c, 0xc0, 0x9f, 0xc0, 0x6b, 0xa5, 0xaa, 0x2f, 0xf3, 0x5c, 0x69, 0xef, 0x9e, 0xef, 0x0d, 0x0e, - 0x87, 0x43, 0x67, 0x83, 0xed, 0x76, 0xee, 0x9b, 0x5c, 0x2d, 0x3b, 0xea, 0x3d, 0x7f, 0x79, 0x67, - 0xe7, 0xaf, 0x97, 0x77, 0x3a, 0x19, 0x8a, 0xc2, 0xbb, 0xfd, 0x6b, 0xc4, 0xfd, 0xe9, 0x31, 0xae, - 0x2f, 0x97, 0xf0, 0x7b, 0x70, 0x94, 0xb0, 0x19, 0x67, 0x01, 0x65, 0x73, 0x9f, 0xc7, 0xd2, 0xde, - 0xd3, 0xd2, 0x1f, 0x6d, 0x24, 0xfd, 0xa8, 0xcc, 0xfc, 0x2e, 0x1e, 0xb5, 0x72, 0xe1, 0xe9, 0xad, - 0xe4, 0x55, 0x48, 0x42, 0x04, 0x4e, 0x23, 0xa4, 0x12, 0x41, 0xfc, 0xa6, 0x46, 0xeb, 0xdc, 0x1a, - 0x1c, 0x0e, 0xdd, 0xb5, 0x1a, 0xa9, 0xe7, 0x7c, 0xab, 0xf3, 0x82, 0x9a, 0x82, 0x9c, 0xc2, 0x82, - 0xac, 0x1e, 0x83, 0x3f, 0x83, 0xee, 0xf5, 0x6d, 0xf6, 0x15, 0xf7, 0x17, 0x84, 0xce, 0x17, 0xca, - 0xbe, 0xa1, 0x9b, 0xf9, 0x7c, 0xa3, 0x66, 0x1e, 0x37, 0xa6, 0x72, 0xc1, 0xbf, 0xd6, 0x14, 0xa6, - 0xaf, 0x4e, 0xba, 0x12, 0x85, 0xbf, 0x5a, 0xe0, 0xac, 0xda, 0x63, 0x14, 0x04, 0x54, 0x51, 0xce, - 0xfc, 0x58, 0xf0, 0x98, 0x4b, 0x14, 0x4a, 0x7b, 0x5f, 0x17, 0xf0, 0xe5, 0x56, 0x83, 0xbc, 0x67, - 0x68, 0x26, 0x86, 0xc5, 0x94, 0x70, 0x1b, 0xaf, 0xc1, 0x25, 0xfc, 0xc5, 0x02, 0xdd, 0xaa, 0x0a, - 0x41, 0x22, 0x9e, 0xa2, 0xb0, 0x56, 0xc4, 0x4d, 0x5d, 0xc4, 0x17, 0x5b, 0x15, 0x31, 0x2d, 0x58, - 0xae, 0xd5, 0x60, 0xe3, 0xd5, 0xb0, 0x84, 0x63, 0xb0, 0x1f, 0x23, 0x81, 0x22, 0x69, 0x1f, 0xe8, - 0xe1, 0xbe, 0xbf, 0x91, 0xda, 0x44, 0xa7, 0x18, 0x72, 0x43, 0xa0, 0xbb, 0x49, 0x51, 0x48, 0x03, - 0xa4, 0xb8, 0xf0, 0xab, 0xbe, 0xe2, 0x64, 0x96, 0xdf, 0x37, 0xbb, 0xbd, 0x45, 0x37, 0x8f, 0x4b, - 0x9a, 0xb2, 0xad, 0x49, 0x32, 0xfb, 0x86, 0x64, 0x65, 0x37, 0xe9, 0x0a, 0x38, 0xd7, 0x80, 0xcf, - 0x2c, 0x70, 0x56, 0x81, 0xd2, 0x9f, 0x65, 0x7e, 0x7d, 0xc8, 0xc2, 0x06, 0xff, 0xa7, 0x86, 0x51, - 0x56, 0x9b, 0xb0, 0xf8, 0x47, 0x0d, 0xb2, 0x89, 0xc3, 0x14, 0xbc, 0xd9, 0x10, 0x95, 0xf9, 0xb9, - 0x8e, 0x45, 0xc2, 0x88, 0x7d, 0xa8, 0xe5, 0x3f, 0xdb, 0xf6, 0x54, 0x09, 0x79, 0xc1, 0x27, 0x39, - 0x81, 0xd1, 0x3e, 0xc5, 0x2b, 0xb0, 0xfe, 0xb3, 0x16, 0x38, 0x6a, 0x78, 0x0a, 0xbc, 0x0d, 0x0e, - 0x0a, 0x11, 0x63, 0x61, 0xed, 0xe9, 0x4d, 0xfd, 0x3d, 0x0e, 0xe0, 0xdb, 0x00, 0xe0, 0x05, 0x62, - 0x8c, 0x84, 0x39, 0xb8, 0xab, 0xc1, 0xb6, 0x89, 0x8c, 0x03, 0x78, 0x06, 0xda, 0x38, 0xa4, 0x84, - 0xa9, 0x1c, 0xdd, 0xd3, 0xe8, 0x41, 0x11, 0x18, 0x07, 0xf0, 0x3d, 0x70, 0x4c, 0x19, 0x55, 0x14, - 0x85, 0xe5, 0x75, 0x6d, 0x69, 0x7f, 0x3c, 0x32, 0x51, 0x73, 0xc5, 0x66, 0xe0, 0xa4, 0xda, 0x07, - 0xe3, 0xc8, 0xf6, 0x0d, 0x7d, 0xc6, 0xbc, 0xb5, 0x1b, 0x50, 0xb9, 0x7d, 0xea, 0x39, 0x75, 0x57, - 0x36, 0x8d, 0x57, 0x7e, 0x6b, 0x30, 0xa8, 0x40, 0x27, 0x26, 0x85, 0x3f, 0x19, 0x37, 0xc9, 0x7b, - 0x98, 0x93, 0xf2, 0x02, 0x7f, 0xfa, 0x6f, 0x56, 0x55, 0x0d, 0xf8, 0x21, 0x51, 0xf7, 0x75, 0xda, - 0x04, 0xe1, 0x25, 0x51, 0x0f, 0x90, 0x42, 0xe5, 0x4e, 0x1b, 0xf6, 0xc2, 0x63, 0x8a, 0x45, 0x12, - 0x7e, 0x00, 0xa0, 0x0c, 0x91, 0x5c, 0xf8, 0x01, 0xff, 0x91, 0x29, 0x1a, 0x11, 0x1f, 0xe1, 0xa5, - 0xbe, 0xad, 0xed, 0xe9, 0x89, 0x46, 0x1e, 0x18, 0xe0, 0x1e, 0x5e, 0xc2, 0x1f, 0xc0, 0x1b, 0x0d, - 0x17, 0xf5, 0x29, 0x0b, 0xc8, 0x53, 0xfb, 0x40, 0x17, 0xf8, 0xc9, 0x66, 0x47, 0x51, 0xe2, 0xba, - 0x79, 0x9a, 0xe2, 0x5e, 0xaf, 0x7b, 0xf6, 0x38, 0x27, 0xed, 0x3f, 0x01, 0x9d, 0xd5, 0x76, 0xb8, - 0xc5, 0xb3, 0xd6, 0x01, 0xfb, 0x66, 0xac, 0xbb, 0x1a, 0x37, 0x5f, 0xa3, 0x8b, 0xe7, 0x97, 0x3d, - 0xeb, 0xc5, 0x65, 0xcf, 0xfa, 0xf3, 0xb2, 0x67, 0xfd, 0x76, 0xd5, 0xdb, 0x79, 0x71, 0xd5, 0xdb, - 0xf9, 0xe3, 0xaa, 0xb7, 0xf3, 0xe4, 0xee, 0x9c, 0xaa, 0x45, 0x32, 0x73, 0x30, 0x8f, 0x5c, 0xcc, - 0x65, 0xc4, 0xa5, 0xfb, 0xaa, 0xab, 0x0f, 0xab, 0x67, 0xfa, 0x69, 0xf3, 0x0f, 0x81, 0xca, 0x62, - 0x22, 0x67, 0xfb, 0xfa, 0x19, 0xfe, 0xf8, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x19, 0x84, - 0x4a, 0xd5, 0x08, 0x00, 0x00, + 0x48, 0x91, 0x00, 0x1b, 0x07, 0x2e, 0xf8, 0xeb, 0x45, 0xd3, 0x4a, 0x10, 0x21, 0x44, 0x94, 0xfe, + 0x20, 0x95, 0x0b, 0x6b, 0x32, 0x1e, 0x25, 0x43, 0xec, 0x19, 0x6b, 0x66, 0x6c, 0x6a, 0x21, 0x24, + 0x2a, 0x5e, 0x80, 0xb7, 0xa2, 0x97, 0xbd, 0xe4, 0xaa, 0x42, 0xbb, 0x6f, 0xc0, 0x13, 0x20, 0x8f, + 0xc7, 0xae, 0xbd, 0x24, 0x90, 0xf4, 0x2e, 0x3e, 0xdf, 0x9c, 0xef, 0x3b, 0x67, 0xce, 0xcc, 0x37, + 0x01, 0x1e, 0x65, 0x8a, 0x08, 0xbc, 0x40, 0x94, 0xf9, 0x92, 0xe0, 0x44, 0x50, 0x95, 0xb9, 0x18, + 0xa7, 0x6e, 0x2c, 0x78, 0x4a, 0x03, 0x22, 0xdc, 0xd4, 0x73, 0xe7, 0x84, 0x11, 0x49, 0xa5, 0x13, + 0x0b, 0xae, 0x38, 0x7c, 0x67, 0x45, 0x8a, 0x83, 0x71, 0xea, 0x94, 0x29, 0x4e, 0xea, 0x75, 0x4f, + 0xe7, 0x7c, 0xce, 0xf5, 0x7a, 0x37, 0xff, 0x55, 0xa4, 0x76, 0xdf, 0x5d, 0xa7, 0x96, 0x7a, 0xae, + 0x61, 0x50, 0xbc, 0x3b, 0xdc, 0xa4, 0xa6, 0x4a, 0xec, 0x7f, 0x72, 0x30, 0x67, 0x32, 0x89, 0x8a, + 0x9c, 0xf2, 0xb7, 0xc9, 0xf1, 0x36, 0xc9, 0x69, 0xf4, 0xde, 0x7d, 0x4b, 0x11, 0x16, 0x10, 0x11, + 0x51, 0xa6, 0x5c, 0x2c, 0xb2, 0x58, 0x71, 0x77, 0x49, 0x32, 0x83, 0xf6, 0xff, 0x68, 0x83, 0x1b, + 0x5f, 0x15, 0xeb, 0xef, 0x2b, 0xa4, 0x08, 0x1c, 0x80, 0x93, 0x14, 0x85, 0x92, 0x28, 0x3f, 0x89, + 0x03, 0xa4, 0x88, 0x4f, 0x03, 0xdb, 0x3a, 0xb7, 0x06, 0xad, 0xe9, 0x71, 0x11, 0x7f, 0xa8, 0xc3, + 0xe3, 0x00, 0xfe, 0x0c, 0x5e, 0x2b, 0x55, 0x7d, 0x99, 0xe7, 0x4a, 0x7b, 0xf7, 0x7c, 0x6f, 0x70, + 0x38, 0x1c, 0x3a, 0x1b, 0x6c, 0xb7, 0x73, 0xd7, 0xe4, 0x6a, 0xd9, 0x51, 0xef, 0xd9, 0x8b, 0x5b, + 0x3b, 0x7f, 0xbf, 0xb8, 0xd5, 0xc9, 0x50, 0x14, 0x7e, 0xde, 0xbf, 0x42, 0xdc, 0x9f, 0x1e, 0xe3, + 0xfa, 0x72, 0x09, 0x7f, 0x00, 0x47, 0x09, 0x9b, 0x71, 0x16, 0x50, 0x36, 0xf7, 0x79, 0x2c, 0xed, + 0x3d, 0x2d, 0xfd, 0xd1, 0x46, 0xd2, 0x0f, 0xcb, 0xcc, 0xef, 0xe2, 0x51, 0x2b, 0x17, 0x9e, 0xde, + 0x48, 0x5e, 0x86, 0x24, 0x44, 0xe0, 0x34, 0x42, 0x2a, 0x11, 0xc4, 0x6f, 0x6a, 0xb4, 0xce, 0xad, + 0xc1, 0xe1, 0xd0, 0x5d, 0xab, 0x91, 0x7a, 0xce, 0xb7, 0x3a, 0x2f, 0xa8, 0x29, 0xc8, 0x29, 0x2c, + 0xc8, 0xea, 0x31, 0xf8, 0x0b, 0xe8, 0x5e, 0xdd, 0x66, 0x5f, 0x71, 0x7f, 0x41, 0xe8, 0x7c, 0xa1, + 0xec, 0x6b, 0xba, 0x99, 0x2f, 0x36, 0x6a, 0xe6, 0x51, 0x63, 0x2a, 0x0f, 0xf8, 0xd7, 0x9a, 0xc2, + 0xf4, 0xd5, 0x49, 0x57, 0xa2, 0xf0, 0x37, 0x0b, 0x9c, 0x55, 0x7b, 0x8c, 0x82, 0x80, 0x2a, 0xca, + 0x99, 0x1f, 0x0b, 0x1e, 0x73, 0x89, 0x42, 0x69, 0xef, 0xeb, 0x02, 0x6e, 0x6f, 0x35, 0xc8, 0x3b, + 0x86, 0x66, 0x62, 0x58, 0x4c, 0x09, 0x37, 0xf1, 0x1a, 0x5c, 0xc2, 0x5f, 0x2d, 0xd0, 0xad, 0xaa, + 0x10, 0x24, 0xe2, 0x29, 0x0a, 0x6b, 0x45, 0x5c, 0xd7, 0x45, 0x7c, 0xb9, 0x55, 0x11, 0xd3, 0x82, + 0xe5, 0x4a, 0x0d, 0x36, 0x5e, 0x0d, 0x4b, 0x38, 0x06, 0xfb, 0x31, 0x12, 0x28, 0x92, 0xf6, 0x81, + 0x1e, 0xee, 0xfb, 0x1b, 0xa9, 0x4d, 0x74, 0x8a, 0x21, 0x37, 0x04, 0xba, 0x9b, 0x14, 0x85, 0x34, + 0x40, 0x8a, 0x0b, 0xbf, 0xea, 0x2b, 0x4e, 0x66, 0xf9, 0x7d, 0xb3, 0xdb, 0x5b, 0x74, 0xf3, 0xa8, + 0xa4, 0x29, 0xdb, 0x9a, 0x24, 0xb3, 0x6f, 0x48, 0x56, 0x76, 0x93, 0xae, 0x80, 0x73, 0x0d, 0xf8, + 0xd4, 0x02, 0x67, 0x15, 0x28, 0xfd, 0x59, 0xe6, 0xd7, 0x87, 0x2c, 0x6c, 0xf0, 0x2a, 0x35, 0x8c, + 0xb2, 0xda, 0x84, 0xc5, 0xbf, 0x6a, 0x90, 0x4d, 0x1c, 0xa6, 0xe0, 0xcd, 0x86, 0xa8, 0xcc, 0xcf, + 0x75, 0x2c, 0x12, 0x46, 0xec, 0x43, 0x2d, 0xff, 0xd9, 0xb6, 0xa7, 0x4a, 0xc8, 0x07, 0x7c, 0x92, + 0x13, 0x18, 0xed, 0x53, 0xbc, 0x02, 0xeb, 0x3f, 0x6d, 0x81, 0xa3, 0x86, 0xa7, 0xc0, 0x9b, 0xe0, + 0xa0, 0x10, 0x31, 0x16, 0xd6, 0x9e, 0x5e, 0xd7, 0xdf, 0xe3, 0x00, 0xbe, 0x0d, 0x00, 0x5e, 0x20, + 0xc6, 0x48, 0x98, 0x83, 0xbb, 0x1a, 0x6c, 0x9b, 0xc8, 0x38, 0x80, 0x67, 0xa0, 0x8d, 0x43, 0x4a, + 0x98, 0xca, 0xd1, 0x3d, 0x8d, 0x1e, 0x14, 0x81, 0x71, 0x00, 0xdf, 0x03, 0xc7, 0x94, 0x51, 0x45, + 0x51, 0x58, 0x5e, 0xd7, 0x96, 0xf6, 0xc7, 0x23, 0x13, 0x35, 0x57, 0x6c, 0x06, 0x4e, 0xaa, 0x7d, + 0x30, 0x8e, 0x6c, 0x5f, 0xd3, 0x67, 0xcc, 0x5b, 0xbb, 0x01, 0x95, 0xdb, 0xa7, 0x9e, 0x53, 0x77, + 0x65, 0xd3, 0x78, 0xe5, 0xb7, 0x06, 0x83, 0x0a, 0x74, 0x62, 0x52, 0xf8, 0x93, 0x71, 0x93, 0xbc, + 0x87, 0x39, 0x29, 0x2f, 0xf0, 0xa7, 0xff, 0x65, 0x55, 0xd5, 0x80, 0xef, 0x13, 0x75, 0x57, 0xa7, + 0x4d, 0x10, 0x5e, 0x12, 0x75, 0x0f, 0x29, 0x54, 0xee, 0xb4, 0x61, 0x2f, 0x3c, 0xa6, 0x58, 0x24, + 0xe1, 0x07, 0x00, 0xca, 0x10, 0xc9, 0x85, 0x1f, 0xf0, 0x9f, 0x98, 0xa2, 0x11, 0xf1, 0x11, 0x5e, + 0xea, 0xdb, 0xda, 0x9e, 0x9e, 0x68, 0xe4, 0x9e, 0x01, 0xee, 0xe0, 0x25, 0xfc, 0x11, 0xbc, 0xd1, + 0x70, 0x51, 0x9f, 0xb2, 0x80, 0x3c, 0xb1, 0x0f, 0x74, 0x81, 0x9f, 0x6c, 0x76, 0x14, 0x25, 0xae, + 0x9b, 0xa7, 0x29, 0xee, 0xf5, 0xba, 0x67, 0x8f, 0x73, 0xd2, 0xfe, 0x63, 0xd0, 0x59, 0x6d, 0x87, + 0x5b, 0x3c, 0x6b, 0x1d, 0xb0, 0x6f, 0xc6, 0xba, 0xab, 0x71, 0xf3, 0x35, 0xfa, 0xfe, 0xd9, 0x45, + 0xcf, 0x7a, 0x7e, 0xd1, 0xb3, 0xfe, 0xba, 0xe8, 0x59, 0xbf, 0x5f, 0xf6, 0x76, 0x9e, 0x5f, 0xf6, + 0x76, 0xfe, 0xbc, 0xec, 0xed, 0x3c, 0xbe, 0x3d, 0xa7, 0x6a, 0x91, 0xcc, 0x1c, 0xcc, 0x23, 0x17, + 0x73, 0x19, 0x71, 0xe9, 0xbe, 0xec, 0xea, 0xc3, 0xea, 0x99, 0x4e, 0x87, 0xee, 0x93, 0xe6, 0x7f, + 0x02, 0x95, 0xc5, 0x44, 0xce, 0xf6, 0xf5, 0x4b, 0xfc, 0xf1, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xae, 0x7b, 0x97, 0x91, 0xd8, 0x08, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/provider/types/genesis_test.go b/x/ccv/provider/types/genesis_test.go index a967de18a9..0bf3b98a55 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -6,13 +6,16 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/testutil/crypto" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/x/ccv/types" + + "github.com/cosmos/interchain-security/v2/testutil/crypto" + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v2/x/ccv/types" + "github.com/stretchr/testify/require" ) @@ -74,7 +77,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -93,7 +96,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -112,7 +115,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -131,7 +134,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -156,7 +159,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -181,7 +184,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -206,7 +209,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000000)}), nil, nil, nil, @@ -231,7 +234,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -256,7 +259,7 @@ func TestValidateGenesisState(t *testing.T) { 0, // 0 vsc timeout here types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -281,7 +284,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, 0, // 0 slash meter replenish period here types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -306,7 +309,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - types.DefaultMaxThrottledPackets), + types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -331,7 +334,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - -1), + -1, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -643,6 +646,44 @@ func TestValidateGenesisState(t *testing.T) { ), false, }, + { + "invalid params- invalid consumer registration fee denom", + types.NewGenesisState( + types.DefaultValsetUpdateID, + nil, + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, + nil, + nil, + nil, + nil, + types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}), + nil, + nil, + nil, + ), + false, + }, + { + "invalid params- invalid consumer registration fee amount", + types.NewGenesisState( + types.DefaultValsetUpdateID, + nil, + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, + nil, + nil, + nil, + nil, + types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", 400, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-1000000)}), + nil, + nil, + nil, + ), + false, + }, } for _, tc := range testCases { diff --git a/x/ccv/provider/types/key_assignment.go b/x/ccv/provider/types/key_assignment.go index 19b83eca6d..3ecee9379a 100644 --- a/x/ccv/provider/types/key_assignment.go +++ b/x/ccv/provider/types/key_assignment.go @@ -4,11 +4,23 @@ import ( "fmt" "strings" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) +// A validator's consensus address on the provider chain. +type ProviderConsAddress struct { + Address sdk.ConsAddress +} + +// A validator's assigned consensus address for a consumer chain. +// Note this type is for type safety within provider code, consumer code uses normal sdk.ConsAddress, +// since there's no notion of provider vs consumer address. +type ConsumerConsAddress struct { + Address sdk.ConsAddress +} + // NewProviderConsAddress creates a new ProviderConsAddress, // a validator's consensus address on the provider chain. func NewProviderConsAddress(addr sdk.ConsAddress) ProviderConsAddress { @@ -18,7 +30,7 @@ func NewProviderConsAddress(addr sdk.ConsAddress) ProviderConsAddress { } func (p *ProviderConsAddress) ToSdkConsAddr() sdk.ConsAddress { - return sdk.ConsAddress(p.Address) + return p.Address } // String implements the Stringer interface for ProviderConsAddress, @@ -38,7 +50,7 @@ func NewConsumerConsAddress(addr sdk.ConsAddress) ConsumerConsAddress { } func (c *ConsumerConsAddress) ToSdkConsAddr() sdk.ConsAddress { - return sdk.ConsAddress(c.Address) + return c.Address } // String implements the Stringer interface for ConsumerConsAddress, @@ -57,34 +69,34 @@ func KeyAssignmentValidateBasic( ) error { for _, e := range assignedKeys { if strings.TrimSpace(e.ChainId) == "" { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") } - if err := sdk.VerifyAddressFormat(e.ProviderAddr.ToSdkConsAddr()); err != nil { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid provider address: %s", e.ProviderAddr)) + if err := sdk.VerifyAddressFormat(e.ProviderAddr); err != nil { + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid provider address: %s", e.ProviderAddr)) } if e.ConsumerKey == nil { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer key: %s", e.ConsumerKey)) + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer key: %s", e.ConsumerKey)) } } for _, e := range byConsumerAddrs { if strings.TrimSpace(e.ChainId) == "" { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") } - if err := sdk.VerifyAddressFormat(e.ProviderAddr.ToSdkConsAddr()); err != nil { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid provider address: %s", e.ProviderAddr)) + if err := sdk.VerifyAddressFormat(e.ProviderAddr); err != nil { + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid provider address: %s", e.ProviderAddr)) } - if err := sdk.VerifyAddressFormat(e.ConsumerAddr.ToSdkConsAddr()); err != nil { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer address: %s", e.ConsumerAddr)) + if err := sdk.VerifyAddressFormat(e.ConsumerAddr); err != nil { + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer address: %s", e.ConsumerAddr)) } } for _, e := range consumerAddrsToPrune { if strings.TrimSpace(e.ChainId) == "" { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, "consumer chain id must not be blank") } // Don't check e.vscid, it's an unsigned integer for _, a := range e.ConsumerAddrs.Addresses { - if err := sdk.VerifyAddressFormat(a.ToSdkConsAddr()); err != nil { - return sdkerrors.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer address: %s", a)) + if err := sdk.VerifyAddressFormat(a); err != nil { + return errorsmod.Wrap(ccvtypes.ErrInvalidGenesis, fmt.Sprintf("invalid consumer address: %s", a)) } } } diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index 18218cf560..4e15f566ef 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) type Status int @@ -28,6 +28,9 @@ const ( // Default validator set update ID DefaultValsetUpdateID = 1 + + // This address receives rewards from consumer chains + ConsumerRewardsPool = "consumer_rewards_pool" ) // Iota generated keys/byte prefixes (as a byte), supports 256 possible values @@ -128,6 +131,13 @@ const ( // denoting whether the provider address has committed any double signign infractions SlashLogBytePrefix + // ConsumerRewardDenomsBytePrefix is the byte prefix that will store a list of consumer reward denoms + ConsumerRewardDenomsBytePrefix + + // VSCMaturedHandledThisBlockBytePrefix is the byte prefix storing the number of vsc matured packets + // handled in the current block + VSCMaturedHandledThisBlockBytePrefix + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -362,6 +372,11 @@ func SlashLogKey(providerAddr ProviderConsAddress) []byte { return append([]byte{SlashLogBytePrefix}, providerAddr.ToSdkConsAddr().Bytes()...) } +// ConsumerRewardDenomsKey returns the key under which consumer reward denoms are stored +func ConsumerRewardDenomsKey(denom string) []byte { + return append([]byte{ConsumerRewardDenomsBytePrefix}, []byte(denom)...) +} + // NOTE: DO NOT ADD FULLY DEFINED KEY FUNCTIONS WITHOUT ADDING THEM TO getAllFullyDefinedKeys() IN keys_test.go // @@ -465,6 +480,10 @@ func ParseChainIdAndConsAddrKey(prefix byte, bz []byte) (string, sdk.ConsAddress return chainID, addr, nil } +func VSCMaturedHandledThisBlockKey() []byte { + return []byte{VSCMaturedHandledThisBlockBytePrefix} +} + // // End of generic helpers section // diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index bc9626553c..03493c1138 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -5,8 +5,8 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" - cryptoutil "github.com/cosmos/interchain-security/testutil/crypto" - providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types" + cryptoutil "github.com/cosmos/interchain-security/v2/testutil/crypto" + providertypes "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" "github.com/stretchr/testify/require" ) @@ -51,6 +51,7 @@ func getAllKeyPrefixes() []byte { providertypes.KeyAssignmentReplacementsBytePrefix, providertypes.ConsumerAddrsToPruneBytePrefix, providertypes.SlashLogBytePrefix, + providertypes.VSCMaturedHandledThisBlockBytePrefix, } } @@ -94,6 +95,7 @@ func getAllFullyDefinedKeys() [][]byte { providertypes.KeyAssignmentReplacementsKey("chainID", providertypes.NewProviderConsAddress([]byte{0x05})), providertypes.ConsumerAddrsToPruneKey("chainID", 88), providertypes.SlashLogKey(providertypes.NewProviderConsAddress([]byte{0x05})), + providertypes.VSCMaturedHandledThisBlockKey(), } } diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 901aa03600..67ad99d10c 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -9,7 +9,8 @@ import ( // provider message types const ( - TypeMsgAssignConsumerKey = "assign_consumer_key" + TypeMsgAssignConsumerKey = "assign_consumer_key" + TypeMsgRegisterConsumerRewardDenom = "register_consumer_reward_denom" ) var _ sdk.Msg = &MsgAssignConsumerKey{} @@ -93,3 +94,48 @@ func ParseConsumerKeyFromJson(jsonStr string) (pkType, key string, err error) { } return pubKey.Type, pubKey.Key, nil } + +// NewMsgRegisterConsumerRewardDenom returns a new MsgRegisterConsumerRewardDenom with a sender and +// a funding amount. +func NewMsgRegisterConsumerRewardDenom(denom string, depositor sdk.AccAddress) *MsgRegisterConsumerRewardDenom { + return &MsgRegisterConsumerRewardDenom{ + Denom: denom, + Depositor: depositor.String(), + } +} + +// Route returns the MsgRegisterConsumerRewardDenom message route. +func (msg MsgRegisterConsumerRewardDenom) Route() string { return ModuleName } + +// Type returns the MsgRegisterConsumerRewardDenom message type. +func (msg MsgRegisterConsumerRewardDenom) Type() string { return TypeMsgRegisterConsumerRewardDenom } + +// GetSigners returns the signer addresses that are expected to sign the result +// of GetSignBytes. +func (msg MsgRegisterConsumerRewardDenom) GetSigners() []sdk.AccAddress { + depoAddr, err := sdk.AccAddressFromBech32(msg.Depositor) + if err != nil { + panic(err) + } + return []sdk.AccAddress{depoAddr} +} + +// GetSignBytes returns the raw bytes for a MsgRegisterConsumerRewardDenom message that +// the expected signer needs to sign. +func (msg MsgRegisterConsumerRewardDenom) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(&msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic performs basic MsgRegisterConsumerRewardDenom message validation. +func (msg MsgRegisterConsumerRewardDenom) ValidateBasic() error { + if !sdk.NewCoin(msg.Denom, sdk.NewInt(0)).IsValid() { + return ErrInvalidConsumerRewardDenom + } + _, err := sdk.AccAddressFromBech32(msg.Depositor) + if err != nil { + return ErrInvalidDepositorAddress + } + + return nil +} diff --git a/x/ccv/provider/types/params.go b/x/ccv/provider/types/params.go index 27a9cf9c01..487fdda366 100644 --- a/x/ccv/provider/types/params.go +++ b/x/ccv/provider/types/params.go @@ -4,12 +4,15 @@ import ( "fmt" "time" + sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + consumertypes "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) const ( @@ -42,13 +45,14 @@ const ( // Reflection based keys for params subspace var ( - KeyTemplateClient = []byte("TemplateClient") - KeyTrustingPeriodFraction = []byte("TrustingPeriodFraction") - KeyInitTimeoutPeriod = []byte("InitTimeoutPeriod") - KeyVscTimeoutPeriod = []byte("VscTimeoutPeriod") - KeySlashMeterReplenishPeriod = []byte("SlashMeterReplenishPeriod") - KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction") - KeyMaxThrottledPackets = []byte("MaxThrottledPackets") + KeyTemplateClient = []byte("TemplateClient") + KeyTrustingPeriodFraction = []byte("TrustingPeriodFraction") + KeyInitTimeoutPeriod = []byte("InitTimeoutPeriod") + KeyVscTimeoutPeriod = []byte("VscTimeoutPeriod") + KeySlashMeterReplenishPeriod = []byte("SlashMeterReplenishPeriod") + KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction") + KeyMaxThrottledPackets = []byte("MaxThrottledPackets") + KeyConsumerRewardDenomRegistrationFee = []byte("ConsumerRewardDenomRegistrationFee") ) // ParamKeyTable returns a key table with the necessary registered provider params @@ -66,16 +70,18 @@ func NewParams( slashMeterReplenishPeriod time.Duration, slashMeterReplenishFraction string, maxThrottledPackets int64, + consumerRewardDenomRegistrationFee sdk.Coin, ) Params { return Params{ - TemplateClient: cs, - TrustingPeriodFraction: trustingPeriodFraction, - CcvTimeoutPeriod: ccvTimeoutPeriod, - InitTimeoutPeriod: initTimeoutPeriod, - VscTimeoutPeriod: vscTimeoutPeriod, - SlashMeterReplenishPeriod: slashMeterReplenishPeriod, - SlashMeterReplenishFraction: slashMeterReplenishFraction, - MaxThrottledPackets: maxThrottledPackets, + TemplateClient: cs, + TrustingPeriodFraction: trustingPeriodFraction, + CcvTimeoutPeriod: ccvTimeoutPeriod, + InitTimeoutPeriod: initTimeoutPeriod, + VscTimeoutPeriod: vscTimeoutPeriod, + SlashMeterReplenishPeriod: slashMeterReplenishPeriod, + SlashMeterReplenishFraction: slashMeterReplenishFraction, + MaxThrottledPackets: maxThrottledPackets, + ConsumerRewardDenomRegistrationFee: consumerRewardDenomRegistrationFee, } } @@ -101,6 +107,12 @@ func DefaultParams() Params { DefaultSlashMeterReplenishPeriod, DefaultSlashMeterReplenishFraction, DefaultMaxThrottledPackets, + // Defining this inline because it's not possible to define a constant of type sdk.Coin. + // Following the pattern from cosmos-sdk/staking/types/params.go + sdk.Coin{ + Denom: sdk.DefaultBondDenom, + Amount: sdk.NewInt(10000000), + }, ) } @@ -109,7 +121,7 @@ func (p Params) Validate() error { if p.TemplateClient == nil { return fmt.Errorf("template client is nil") } - if err := validateTemplateClient(*p.TemplateClient); err != nil { + if err := ValidateTemplateClient(*p.TemplateClient); err != nil { return err } if err := ccvtypes.ValidateStringFraction(p.TrustingPeriodFraction); err != nil { @@ -133,13 +145,16 @@ func (p Params) Validate() error { if err := ccvtypes.ValidatePositiveInt64(p.MaxThrottledPackets); err != nil { return fmt.Errorf("max throttled packets is invalid: %s", err) } + if err := ValidateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil { + return fmt.Errorf("consumer reward denom registration fee is invalid: %s", err) + } return nil } // ParamSetPairs implements params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyTemplateClient, p.TemplateClient, validateTemplateClient), + paramtypes.NewParamSetPair(KeyTemplateClient, p.TemplateClient, ValidateTemplateClient), paramtypes.NewParamSetPair(KeyTrustingPeriodFraction, p.TrustingPeriodFraction, ccvtypes.ValidateStringFraction), paramtypes.NewParamSetPair(ccvtypes.KeyCCVTimeoutPeriod, p.CcvTimeoutPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeyInitTimeoutPeriod, p.InitTimeoutPeriod, ccvtypes.ValidateDuration), @@ -147,10 +162,11 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeySlashMeterReplenishPeriod, p.SlashMeterReplenishPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeySlashMeterReplenishFraction, p.SlashMeterReplenishFraction, ccvtypes.ValidateStringFraction), paramtypes.NewParamSetPair(KeyMaxThrottledPackets, p.MaxThrottledPackets, ccvtypes.ValidatePositiveInt64), + paramtypes.NewParamSetPair(KeyConsumerRewardDenomRegistrationFee, p.ConsumerRewardDenomRegistrationFee, ValidateCoin), } } -func validateTemplateClient(i interface{}) error { +func ValidateTemplateClient(i interface{}) error { cs, ok := i.(ibctmtypes.ClientState) if !ok { return fmt.Errorf("invalid parameter type: %T, expected: %T", i, ibctmtypes.ClientState{}) @@ -176,3 +192,16 @@ func validateTemplateClient(i interface{}) error { } return nil } + +func ValidateCoin(i interface{}) error { + v, ok := i.(sdk.Coin) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if !v.IsValid() { + return fmt.Errorf("invalid consumer reward denom registration fee: %s", v) + } + + return nil +} diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index c6c1a901b0..bca99670a9 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -4,12 +4,13 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/stretchr/testify/require" - - "github.com/cosmos/interchain-security/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) func TestValidateParams(t *testing.T) { @@ -19,37 +20,45 @@ func TestValidateParams(t *testing.T) { expPass bool }{ {"default params", types.DefaultParams(), true}, - {"custom valid params", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), true}, - {"custom invalid params", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), false}, + {"custom valid params", types.NewParams( + ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), true}, + {"custom invalid params", types.NewParams( + ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), false}, - {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, // Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), true}, + "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), true}, {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", 100), false}, + "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"0 init timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", 100), false}, + "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"0 vsc timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", 100), false}, + "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"0 slash meter replenish period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", 100), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"slash meter replenish fraction over 1", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", 100), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, {"negative max pending slash packets", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", -100), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", -100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + {"invalid consumer reward denom registration fee denom", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", -100, sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}), false}, + {"invalid consumer reward denom registration fee amount", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", -100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-10000000)}), false}, } for _, tc := range testCases { diff --git a/x/ccv/provider/types/proposal.go b/x/ccv/provider/types/proposal.go index 39867d18e9..43f5d027eb 100644 --- a/x/ccv/provider/types/proposal.go +++ b/x/ccv/provider/types/proposal.go @@ -6,11 +6,12 @@ import ( "strings" time "time" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ccvtypes "github.com/cosmos/interchain-security/x/ccv/types" + + ccvtypes "github.com/cosmos/interchain-security/v2/x/ccv/types" ) const ( @@ -36,7 +37,8 @@ func NewConsumerAdditionProposal(title, description, chainID string, initialHeight clienttypes.Height, genesisHash, binaryHash []byte, spawnTime time.Time, consumerRedistributionFraction string, - blocksPerDistributionTransmission, + blocksPerDistributionTransmission int64, + distributionTransmissionChannel string, historicalEntries int64, ccvTimeoutPeriod time.Duration, transferTimeoutPeriod time.Duration, @@ -52,6 +54,7 @@ func NewConsumerAdditionProposal(title, description, chainID string, SpawnTime: spawnTime, ConsumerRedistributionFraction: consumerRedistributionFraction, BlocksPerDistributionTransmission: blocksPerDistributionTransmission, + DistributionTransmissionChannel: distributionTransmissionChannel, HistoricalEntries: historicalEntries, CcvTimeoutPeriod: ccvTimeoutPeriod, TransferTimeoutPeriod: transferTimeoutPeriod, @@ -80,46 +83,50 @@ func (cccp *ConsumerAdditionProposal) ValidateBasic() error { } if strings.TrimSpace(cccp.ChainId) == "" { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "consumer chain id must not be blank") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "consumer chain id must not be blank") } if cccp.InitialHeight.IsZero() { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "initial height cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "initial height cannot be zero") } if len(cccp.GenesisHash) == 0 { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "genesis hash cannot be empty") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "genesis hash cannot be empty") } if len(cccp.BinaryHash) == 0 { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "binary hash cannot be empty") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "binary hash cannot be empty") } if cccp.SpawnTime.IsZero() { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "spawn time cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "spawn time cannot be zero") } if err := ccvtypes.ValidateStringFraction(cccp.ConsumerRedistributionFraction); err != nil { - return sdkerrors.Wrapf(ErrInvalidConsumerAdditionProposal, "consumer redistribution fraction is invalid: %s", err) + return errorsmod.Wrapf(ErrInvalidConsumerAdditionProposal, "consumer redistribution fraction is invalid: %s", err) } if err := ccvtypes.ValidatePositiveInt64(cccp.BlocksPerDistributionTransmission); err != nil { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "blocks per distribution transmission cannot be < 1") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "blocks per distribution transmission cannot be < 1") + } + + if err := ccvtypes.ValidateDistributionTransmissionChannel(cccp.DistributionTransmissionChannel); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "distribution transmission channel") } if err := ccvtypes.ValidatePositiveInt64(cccp.HistoricalEntries); err != nil { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "historical entries cannot be < 1") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "historical entries cannot be < 1") } if err := ccvtypes.ValidateDuration(cccp.CcvTimeoutPeriod); err != nil { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "ccv timeout period cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "ccv timeout period cannot be zero") } if err := ccvtypes.ValidateDuration(cccp.TransferTimeoutPeriod); err != nil { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "transfer timeout period cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "transfer timeout period cannot be zero") } if err := ccvtypes.ValidateDuration(cccp.UnbondingPeriod); err != nil { - return sdkerrors.Wrap(ErrInvalidConsumerAdditionProposal, "unbonding period cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "unbonding period cannot be zero") } return nil @@ -137,6 +144,7 @@ func (cccp *ConsumerAdditionProposal) String() string { SpawnTime: %s ConsumerRedistributionFraction: %s BlocksPerDistributionTransmission: %d + DistributionTransmissionChannel: %s HistoricalEntries: %d CcvTimeoutPeriod: %d TransferTimeoutPeriod: %d @@ -150,6 +158,7 @@ func (cccp *ConsumerAdditionProposal) String() string { cccp.SpawnTime, cccp.ConsumerRedistributionFraction, cccp.BlocksPerDistributionTransmission, + cccp.DistributionTransmissionChannel, cccp.HistoricalEntries, cccp.CcvTimeoutPeriod, cccp.TransferTimeoutPeriod, @@ -179,11 +188,11 @@ func (sccp *ConsumerRemovalProposal) ValidateBasic() error { } if strings.TrimSpace(sccp.ChainId) == "" { - return sdkerrors.Wrap(ErrInvalidConsumerRemovalProp, "consumer chain id must not be blank") + return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "consumer chain id must not be blank") } if sccp.StopTime.IsZero() { - return sdkerrors.Wrap(ErrInvalidConsumerRemovalProp, "spawn time cannot be zero") + return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "spawn time cannot be zero") } return nil } diff --git a/x/ccv/provider/types/proposal_test.go b/x/ccv/provider/types/proposal_test.go index 7572f5a903..4227654bd9 100644 --- a/x/ccv/provider/types/proposal_test.go +++ b/x/ccv/provider/types/proposal_test.go @@ -17,7 +17,8 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - "github.com/cosmos/interchain-security/x/ccv/provider/types" + + "github.com/cosmos/interchain-security/v2/x/ccv/provider/types" ) func TestConsumerAdditionProposalValidateBasic(t *testing.T) { @@ -33,6 +34,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -45,6 +47,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.0", // fraction can be 0.0 but not empty 10, + "", 10000, 100000000000, 100000000000, @@ -56,6 +59,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal(" ", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -67,6 +71,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", " ", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -87,6 +92,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { CcvTimeoutPeriod: 100000000000, TransferTimeoutPeriod: 100000000000, ConsumerRedistributionFraction: "0.75", + DistributionTransmissionChannel: "", HistoricalEntries: 10000, UnbondingPeriod: 100000000000, }, @@ -97,6 +103,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte(""), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -108,6 +115,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte(""), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -119,6 +127,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Time{}, "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -130,6 +139,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "", // fraction can be 0.0 but not empty 10, + "", 10000, 100000000000, 100000000000, @@ -141,17 +151,31 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 0, + "", 100000000000, 10000, 100000000000, 100000000000), false, }, + { + "distribution transmission channel is invalid", + types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), + "0.75", + 10, + "badchannel/", + 10000, + 100000000000, + 100000000000, + 100000000000), + false, + }, { "historical entries is invalid", types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", -2, 100000000000, 100000000000, @@ -163,6 +187,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 0, 100000000000, @@ -174,6 +199,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 0, @@ -185,6 +211,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -208,6 +235,7 @@ func TestMarshalConsumerAdditionProposal(t *testing.T) { content := types.NewConsumerAdditionProposal("title", "description", "chainID", clienttypes.NewHeight(0, 1), []byte("gen_hash"), []byte("bin_hash"), time.Now().UTC(), "0.75", 10, + "", 10000, 100000000000, 100000000000, @@ -249,6 +277,7 @@ func TestConsumerAdditionProposalString(t *testing.T) { spawnTime, "0.75", 10001, + "", 500000, 100000000000, 10000000000, @@ -264,12 +293,14 @@ func TestConsumerAdditionProposalString(t *testing.T) { SpawnTime: %s ConsumerRedistributionFraction: %s BlocksPerDistributionTransmission: %d + DistributionTransmissionChannel: %s HistoricalEntries: %d CcvTimeoutPeriod: %d TransferTimeoutPeriod: %d UnbondingPeriod: %d`, initialHeight, []byte("gen_hash"), []byte("bin_hash"), spawnTime, "0.75", 10001, + "", 500000, 100000000000, 10000000000, diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index e249ccf003..49c2bb7cda 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -6,6 +6,7 @@ package types import ( fmt "fmt" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + types2 "github.com/cosmos/cosmos-sdk/types" types1 "github.com/cosmos/cosmos-sdk/x/evidence/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -32,28 +33,34 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain. -// If it passes, then all validators on the provider chain are expected to validate the consumer chain at spawn time -// or get slashed. It is recommended that spawn time occurs after the proposal end time. +// ConsumerAdditionProposal is a governance proposal on the provider chain to +// spawn a new consumer chain. If it passes, then all validators on the provider +// chain are expected to validate the consumer chain at spawn time or get +// slashed. It is recommended that spawn time occurs after the proposal end +// time. type ConsumerAdditionProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` // the description of the proposal Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // the proposed chain-id of the new consumer chain, must be different from all other consumer chain ids of the executing - // provider chain. + // the proposed chain-id of the new consumer chain, must be different from all + // other consumer chain ids of the executing provider chain. ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // the proposed initial height of new consumer chain. - // For a completely new chain, this will be {0,1}. However, it may be different if this is a chain that is converting to a consumer chain. + // For a completely new chain, this will be {0,1}. However, it may be + // different if this is a chain that is converting to a consumer chain. InitialHeight types.Height `protobuf:"bytes,4,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height"` - // The hash of the consumer chain genesis state without the consumer CCV module genesis params. - // It is used for off-chain confirmation of genesis.json validity by validators and other parties. + // The hash of the consumer chain genesis state without the consumer CCV + // module genesis params. It is used for off-chain confirmation of + // genesis.json validity by validators and other parties. GenesisHash []byte `protobuf:"bytes,5,opt,name=genesis_hash,json=genesisHash,proto3" json:"genesis_hash,omitempty"` - // The hash of the consumer chain binary that should be run by validators on chain initialization. - // It is used for off-chain confirmation of binary validity by validators and other parties. + // The hash of the consumer chain binary that should be run by validators on + // chain initialization. It is used for off-chain confirmation of binary + // validity by validators and other parties. BinaryHash []byte `protobuf:"bytes,6,opt,name=binary_hash,json=binaryHash,proto3" json:"binary_hash,omitempty"` - // spawn time is the time on the provider chain at which the consumer chain genesis is finalized and all validators - // will be responsible for starting their consumer chain validator node. + // spawn time is the time on the provider chain at which the consumer chain + // genesis is finalized and all validators will be responsible for starting + // their consumer chain validator node. SpawnTime time.Time `protobuf:"bytes,7,opt,name=spawn_time,json=spawnTime,proto3,stdtime" json:"spawn_time"` // Unbonding period for the consumer, // which should be smaller than that of the provider in general. @@ -66,13 +73,22 @@ type ConsumerAdditionProposal struct { // during distribution events. The fraction is a string representing a // decimal number. For example "0.75" would represent 75%. ConsumerRedistributionFraction string `protobuf:"bytes,11,opt,name=consumer_redistribution_fraction,json=consumerRedistributionFraction,proto3" json:"consumer_redistribution_fraction,omitempty"` - // BlocksPerDistributionTransmission is the number of blocks between ibc-token-transfers from the consumer chain to the provider chain. - // On sending transmission event, `consumer_redistribution_fraction` of the accumulated tokens are sent to the consumer redistribution address. + // BlocksPerDistributionTransmission is the number of blocks between + // ibc-token-transfers from the consumer chain to the provider chain. On + // sending transmission event, `consumer_redistribution_fraction` of the + // accumulated tokens are sent to the consumer redistribution address. BlocksPerDistributionTransmission int64 `protobuf:"varint,12,opt,name=blocks_per_distribution_transmission,json=blocksPerDistributionTransmission,proto3" json:"blocks_per_distribution_transmission,omitempty"` // The number of historical info entries to persist in store. // This param is a part of the cosmos sdk staking module. In the case of // a ccv enabled consumer chain, the ccv module acts as the staking module. HistoricalEntries int64 `protobuf:"varint,13,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` + // The ID of a token transfer channel used for the Reward Distribution + // sub-protocol. If DistributionTransmissionChannel == "", a new transfer + // channel is created on top of the same connection as the CCV channel. + // Note that transfer_channel_id is the ID of the channel end on the consumer + // chain. it is most relevant for chains performing a sovereign to consumer + // changeover in order to maintan the existing ibc transfer channel + DistributionTransmissionChannel string `protobuf:"bytes,14,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` } func (m *ConsumerAdditionProposal) Reset() { *m = ConsumerAdditionProposal{} } @@ -107,9 +123,10 @@ func (m *ConsumerAdditionProposal) XXX_DiscardUnknown() { var xxx_messageInfo_ConsumerAdditionProposal proto.InternalMessageInfo -// ConsumerRemovalProposal is a governance proposal on the provider chain to remove (and stop) a consumer chain. -// If it passes, all the consumer chain's state is removed from the provider chain. The outstanding unbonding -// operation funds are released. +// ConsumerRemovalProposal is a governance proposal on the provider chain to +// remove (and stop) a consumer chain. If it passes, all the consumer chain's +// state is removed from the provider chain. The outstanding unbonding operation +// funds are released. type ConsumerRemovalProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -117,7 +134,8 @@ type ConsumerRemovalProposal struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // the chain-id of the consumer chain to be stopped ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - // the time on the provider chain at which all validators are responsible to stop their consumer chain validator node + // the time on the provider chain at which all validators are responsible to + // stop their consumer chain validator node StopTime time.Time `protobuf:"bytes,4,opt,name=stop_time,json=stopTime,proto3,stdtime" json:"stop_time"` } @@ -245,8 +263,9 @@ func (m *EquivocationProposal) GetEquivocations() []*types1.Equivocation { return nil } -// A persisted queue entry indicating that a slash packet data instance needs to be handled. -// This type belongs in the "global" queue, to coordinate slash packet handling times between consumers. +// A persisted queue entry indicating that a slash packet data instance needs to +// be handled. This type belongs in the "global" queue, to coordinate slash +// packet handling times between consumers. type GlobalSlashEntry struct { // Block time that slash packet was received by provider chain. // This field is used for store key iteration ordering. @@ -259,8 +278,9 @@ type GlobalSlashEntry struct { // The provider's consensus address of the validator being slashed. // This field is used to obtain validator power in HandleThrottleQueues. // - // This field is not used in the store key, but is persisted in value bytes, see QueueGlobalSlashEntry. - ProviderValConsAddr *ProviderConsAddress `protobuf:"bytes,4,opt,name=provider_val_cons_addr,json=providerValConsAddr,proto3" json:"provider_val_cons_addr,omitempty"` + // This field is not used in the store key, but is persisted in value bytes, + // see QueueGlobalSlashEntry. + ProviderValConsAddr []byte `protobuf:"bytes,4,opt,name=provider_val_cons_addr,json=providerValConsAddr,proto3" json:"provider_val_cons_addr,omitempty"` } func (m *GlobalSlashEntry) Reset() { *m = GlobalSlashEntry{} } @@ -317,7 +337,7 @@ func (m *GlobalSlashEntry) GetIbcSeqNum() uint64 { return 0 } -func (m *GlobalSlashEntry) GetProviderValConsAddr() *ProviderConsAddress { +func (m *GlobalSlashEntry) GetProviderValConsAddr() []byte { if m != nil { return m.ProviderValConsAddr } @@ -327,11 +347,13 @@ func (m *GlobalSlashEntry) GetProviderValConsAddr() *ProviderConsAddress { // Params defines the parameters for CCV Provider module type Params struct { TemplateClient *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=template_client,json=templateClient,proto3" json:"template_client,omitempty"` - // TrustingPeriodFraction is used to compute the consumer and provider IBC client's TrustingPeriod from the chain defined UnbondingPeriod + // TrustingPeriodFraction is used to compute the consumer and provider IBC + // client's TrustingPeriod from the chain defined UnbondingPeriod TrustingPeriodFraction string `protobuf:"bytes,2,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"` // Sent IBC packets will timeout after this duration CcvTimeoutPeriod time.Duration `protobuf:"bytes,3,opt,name=ccv_timeout_period,json=ccvTimeoutPeriod,proto3,stdduration" json:"ccv_timeout_period"` - // The channel initialization (IBC channel opening handshake) will timeout after this duration + // The channel initialization (IBC channel opening handshake) will timeout + // after this duration InitTimeoutPeriod time.Duration `protobuf:"bytes,4,opt,name=init_timeout_period,json=initTimeoutPeriod,proto3,stdduration" json:"init_timeout_period"` // The VSC packets sent by the provider will timeout after this duration. // Note that unlike ccv_timeout_period which is an IBC param, @@ -340,12 +362,15 @@ type Params struct { VscTimeoutPeriod time.Duration `protobuf:"bytes,5,opt,name=vsc_timeout_period,json=vscTimeoutPeriod,proto3,stdduration" json:"vsc_timeout_period"` // The period for which the slash meter is replenished SlashMeterReplenishPeriod time.Duration `protobuf:"bytes,6,opt,name=slash_meter_replenish_period,json=slashMeterReplenishPeriod,proto3,stdduration" json:"slash_meter_replenish_period"` - // The fraction of total voting power that is replenished to the slash meter every replenish period. - // This param also serves as a maximum fraction of total voting power that the slash meter can hold. + // The fraction of total voting power that is replenished to the slash meter + // every replenish period. This param also serves as a maximum fraction of + // total voting power that the slash meter can hold. SlashMeterReplenishFraction string `protobuf:"bytes,7,opt,name=slash_meter_replenish_fraction,json=slashMeterReplenishFraction,proto3" json:"slash_meter_replenish_fraction,omitempty"` // The maximum amount of throttled slash or vsc matured packets // that can be queued for a single consumer before the provider chain halts. MaxThrottledPackets int64 `protobuf:"varint,8,opt,name=max_throttled_packets,json=maxThrottledPackets,proto3" json:"max_throttled_packets,omitempty"` + // The fee required to be paid to add a reward denom + ConsumerRewardDenomRegistrationFee types2.Coin `protobuf:"bytes,9,opt,name=consumer_reward_denom_registration_fee,json=consumerRewardDenomRegistrationFee,proto3" json:"consumer_reward_denom_registration_fee"` } func (m *Params) Reset() { *m = Params{} } @@ -437,6 +462,13 @@ func (m *Params) GetMaxThrottledPackets() int64 { return 0 } +func (m *Params) GetConsumerRewardDenomRegistrationFee() types2.Coin { + if m != nil { + return m.ConsumerRewardDenomRegistrationFee + } + return types2.Coin{} +} + type HandshakeMetadata struct { ProviderFeePoolAddr string `protobuf:"bytes,1,opt,name=provider_fee_pool_addr,json=providerFeePoolAddr,proto3" json:"provider_fee_pool_addr,omitempty"` Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` @@ -535,7 +567,8 @@ func (m *SlashAcks) GetAddresses() []string { return nil } -// ConsumerAdditionProposals holds pending governance proposals on the provider chain to spawn a new chain. +// ConsumerAdditionProposals holds pending governance proposals on the provider +// chain to spawn a new chain. type ConsumerAdditionProposals struct { // proposals waiting for spawn_time to pass Pending []*ConsumerAdditionProposal `protobuf:"bytes,1,rep,name=pending,proto3" json:"pending,omitempty"` @@ -581,7 +614,8 @@ func (m *ConsumerAdditionProposals) GetPending() []*ConsumerAdditionProposal { return nil } -// ConsumerRemovalProposals holds pending governance proposals on the provider chain to remove (and stop) a consumer chain. +// ConsumerRemovalProposals holds pending governance proposals on the provider +// chain to remove (and stop) a consumer chain. type ConsumerRemovalProposals struct { // proposals waiting for stop_time to pass Pending []*ConsumerRemovalProposal `protobuf:"bytes,1,rep,name=pending,proto3" json:"pending,omitempty"` @@ -627,6 +661,51 @@ func (m *ConsumerRemovalProposals) GetPending() []*ConsumerRemovalProposal { return nil } +// AddressList contains a list of consensus addresses +type AddressList struct { + Addresses [][]byte `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` +} + +func (m *AddressList) Reset() { *m = AddressList{} } +func (m *AddressList) String() string { return proto.CompactTextString(m) } +func (*AddressList) ProtoMessage() {} +func (*AddressList) Descriptor() ([]byte, []int) { + return fileDescriptor_f22ec409a72b7b72, []int{9} +} +func (m *AddressList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddressList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddressList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AddressList) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddressList.Merge(m, src) +} +func (m *AddressList) XXX_Size() int { + return m.Size() +} +func (m *AddressList) XXX_DiscardUnknown() { + xxx_messageInfo_AddressList.DiscardUnknown(m) +} + +var xxx_messageInfo_AddressList proto.InternalMessageInfo + +func (m *AddressList) GetAddresses() [][]byte { + if m != nil { + return m.Addresses + } + return nil +} + type ChannelToChain struct { ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -636,7 +715,7 @@ func (m *ChannelToChain) Reset() { *m = ChannelToChain{} } func (m *ChannelToChain) String() string { return proto.CompactTextString(m) } func (*ChannelToChain) ProtoMessage() {} func (*ChannelToChain) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{9} + return fileDescriptor_f22ec409a72b7b72, []int{10} } func (m *ChannelToChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -690,7 +769,7 @@ func (m *VscUnbondingOps) Reset() { *m = VscUnbondingOps{} } func (m *VscUnbondingOps) String() string { return proto.CompactTextString(m) } func (*VscUnbondingOps) ProtoMessage() {} func (*VscUnbondingOps) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{10} + return fileDescriptor_f22ec409a72b7b72, []int{11} } func (m *VscUnbondingOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -745,7 +824,7 @@ func (m *UnbondingOp) Reset() { *m = UnbondingOp{} } func (m *UnbondingOp) String() string { return proto.CompactTextString(m) } func (*UnbondingOp) ProtoMessage() {} func (*UnbondingOp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{11} + return fileDescriptor_f22ec409a72b7b72, []int{12} } func (m *UnbondingOp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -797,7 +876,7 @@ func (m *InitTimeoutTimestamp) Reset() { *m = InitTimeoutTimestamp{} } func (m *InitTimeoutTimestamp) String() string { return proto.CompactTextString(m) } func (*InitTimeoutTimestamp) ProtoMessage() {} func (*InitTimeoutTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{12} + return fileDescriptor_f22ec409a72b7b72, []int{13} } func (m *InitTimeoutTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -849,7 +928,7 @@ func (m *VscSendTimestamp) Reset() { *m = VscSendTimestamp{} } func (m *VscSendTimestamp) String() string { return proto.CompactTextString(m) } func (*VscSendTimestamp) ProtoMessage() {} func (*VscSendTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{13} + return fileDescriptor_f22ec409a72b7b72, []int{14} } func (m *VscSendTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,152 +971,17 @@ func (m *VscSendTimestamp) GetTimestamp() time.Time { return time.Time{} } -// A validator's assigned consensus address for a consumer chain. -// Note this type is for type safety within provider code, consumer code uses normal sdk.ConsAddress, -// since there's no notion of provider vs consumer address. -type ConsumerConsAddress struct { - Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` -} - -func (m *ConsumerConsAddress) Reset() { *m = ConsumerConsAddress{} } -func (*ConsumerConsAddress) ProtoMessage() {} -func (*ConsumerConsAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{14} -} -func (m *ConsumerConsAddress) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConsumerConsAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConsumerConsAddress.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ConsumerConsAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConsumerConsAddress.Merge(m, src) -} -func (m *ConsumerConsAddress) XXX_Size() int { - return m.Size() -} -func (m *ConsumerConsAddress) XXX_DiscardUnknown() { - xxx_messageInfo_ConsumerConsAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_ConsumerConsAddress proto.InternalMessageInfo - -func (m *ConsumerConsAddress) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -// A validator's consensus address on the provider chain -type ProviderConsAddress struct { - Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` -} - -func (m *ProviderConsAddress) Reset() { *m = ProviderConsAddress{} } -func (*ProviderConsAddress) ProtoMessage() {} -func (*ProviderConsAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{15} -} -func (m *ProviderConsAddress) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ProviderConsAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ProviderConsAddress.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ProviderConsAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_ProviderConsAddress.Merge(m, src) -} -func (m *ProviderConsAddress) XXX_Size() int { - return m.Size() -} -func (m *ProviderConsAddress) XXX_DiscardUnknown() { - xxx_messageInfo_ProviderConsAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_ProviderConsAddress proto.InternalMessageInfo - -func (m *ProviderConsAddress) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -// ConsumerAddressList contains a list of consumer consensus addresses -type ConsumerAddressList struct { - Addresses []*ConsumerConsAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` -} - -func (m *ConsumerAddressList) Reset() { *m = ConsumerAddressList{} } -func (m *ConsumerAddressList) String() string { return proto.CompactTextString(m) } -func (*ConsumerAddressList) ProtoMessage() {} -func (*ConsumerAddressList) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{16} -} -func (m *ConsumerAddressList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConsumerAddressList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConsumerAddressList.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ConsumerAddressList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConsumerAddressList.Merge(m, src) -} -func (m *ConsumerAddressList) XXX_Size() int { - return m.Size() -} -func (m *ConsumerAddressList) XXX_DiscardUnknown() { - xxx_messageInfo_ConsumerAddressList.DiscardUnknown(m) -} - -var xxx_messageInfo_ConsumerAddressList proto.InternalMessageInfo - -func (m *ConsumerAddressList) GetAddresses() []*ConsumerConsAddress { - if m != nil { - return m.Addresses - } - return nil -} - type KeyAssignmentReplacement struct { - ProviderAddr *ProviderConsAddress `protobuf:"bytes,1,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` - PrevCKey *crypto.PublicKey `protobuf:"bytes,2,opt,name=prev_c_key,json=prevCKey,proto3" json:"prev_c_key,omitempty"` - Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"` + ProviderAddr []byte `protobuf:"bytes,1,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + PrevCKey *crypto.PublicKey `protobuf:"bytes,2,opt,name=prev_c_key,json=prevCKey,proto3" json:"prev_c_key,omitempty"` + Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"` } func (m *KeyAssignmentReplacement) Reset() { *m = KeyAssignmentReplacement{} } func (m *KeyAssignmentReplacement) String() string { return proto.CompactTextString(m) } func (*KeyAssignmentReplacement) ProtoMessage() {} func (*KeyAssignmentReplacement) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{17} + return fileDescriptor_f22ec409a72b7b72, []int{15} } func (m *KeyAssignmentReplacement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1066,7 +1010,7 @@ func (m *KeyAssignmentReplacement) XXX_DiscardUnknown() { var xxx_messageInfo_KeyAssignmentReplacement proto.InternalMessageInfo -func (m *KeyAssignmentReplacement) GetProviderAddr() *ProviderConsAddress { +func (m *KeyAssignmentReplacement) GetProviderAddr() []byte { if m != nil { return m.ProviderAddr } @@ -1088,18 +1032,19 @@ func (m *KeyAssignmentReplacement) GetPower() int64 { } // Used to serialize the ValidatorConsumerPubKey index from key assignment -// ValidatorConsumerPubKey: (chainID, providerAddr consAddr) -> consumerKey tmprotocrypto.PublicKey +// ValidatorConsumerPubKey: (chainID, providerAddr consAddr) -> consumerKey +// tmprotocrypto.PublicKey type ValidatorConsumerPubKey struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - ProviderAddr *ProviderConsAddress `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` - ConsumerKey *crypto.PublicKey `protobuf:"bytes,3,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ProviderAddr []byte `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + ConsumerKey *crypto.PublicKey `protobuf:"bytes,3,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` } func (m *ValidatorConsumerPubKey) Reset() { *m = ValidatorConsumerPubKey{} } func (m *ValidatorConsumerPubKey) String() string { return proto.CompactTextString(m) } func (*ValidatorConsumerPubKey) ProtoMessage() {} func (*ValidatorConsumerPubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{18} + return fileDescriptor_f22ec409a72b7b72, []int{16} } func (m *ValidatorConsumerPubKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1135,7 +1080,7 @@ func (m *ValidatorConsumerPubKey) GetChainId() string { return "" } -func (m *ValidatorConsumerPubKey) GetProviderAddr() *ProviderConsAddress { +func (m *ValidatorConsumerPubKey) GetProviderAddr() []byte { if m != nil { return m.ProviderAddr } @@ -1150,18 +1095,19 @@ func (m *ValidatorConsumerPubKey) GetConsumerKey() *crypto.PublicKey { } // Used to serialize the ValidatorConsumerAddr index from key assignment -// ValidatorByConsumerAddr: (chainID, consumerAddr consAddr) -> providerAddr consAddr +// ValidatorByConsumerAddr: (chainID, consumerAddr consAddr) -> providerAddr +// consAddr type ValidatorByConsumerAddr struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - ConsumerAddr *ConsumerConsAddress `protobuf:"bytes,2,opt,name=consumer_addr,json=consumerAddr,proto3" json:"consumer_addr,omitempty"` - ProviderAddr *ProviderConsAddress `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ConsumerAddr []byte `protobuf:"bytes,2,opt,name=consumer_addr,json=consumerAddr,proto3" json:"consumer_addr,omitempty"` + ProviderAddr []byte `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` } func (m *ValidatorByConsumerAddr) Reset() { *m = ValidatorByConsumerAddr{} } func (m *ValidatorByConsumerAddr) String() string { return proto.CompactTextString(m) } func (*ValidatorByConsumerAddr) ProtoMessage() {} func (*ValidatorByConsumerAddr) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{19} + return fileDescriptor_f22ec409a72b7b72, []int{17} } func (m *ValidatorByConsumerAddr) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1197,14 +1143,14 @@ func (m *ValidatorByConsumerAddr) GetChainId() string { return "" } -func (m *ValidatorByConsumerAddr) GetConsumerAddr() *ConsumerConsAddress { +func (m *ValidatorByConsumerAddr) GetConsumerAddr() []byte { if m != nil { return m.ConsumerAddr } return nil } -func (m *ValidatorByConsumerAddr) GetProviderAddr() *ProviderConsAddress { +func (m *ValidatorByConsumerAddr) GetProviderAddr() []byte { if m != nil { return m.ProviderAddr } @@ -1214,16 +1160,16 @@ func (m *ValidatorByConsumerAddr) GetProviderAddr() *ProviderConsAddress { // Used to serialize the ConsumerAddrsToPrune index from key assignment // ConsumerAddrsToPrune: (chainID, vscID uint64) -> consumerAddrs AddressList type ConsumerAddrsToPrune struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - VscId uint64 `protobuf:"varint,2,opt,name=vsc_id,json=vscId,proto3" json:"vsc_id,omitempty"` - ConsumerAddrs *ConsumerAddressList `protobuf:"bytes,3,opt,name=consumer_addrs,json=consumerAddrs,proto3" json:"consumer_addrs,omitempty"` + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + VscId uint64 `protobuf:"varint,2,opt,name=vsc_id,json=vscId,proto3" json:"vsc_id,omitempty"` + ConsumerAddrs *AddressList `protobuf:"bytes,3,opt,name=consumer_addrs,json=consumerAddrs,proto3" json:"consumer_addrs,omitempty"` } func (m *ConsumerAddrsToPrune) Reset() { *m = ConsumerAddrsToPrune{} } func (m *ConsumerAddrsToPrune) String() string { return proto.CompactTextString(m) } func (*ConsumerAddrsToPrune) ProtoMessage() {} func (*ConsumerAddrsToPrune) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{20} + return fileDescriptor_f22ec409a72b7b72, []int{18} } func (m *ConsumerAddrsToPrune) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1266,7 +1212,7 @@ func (m *ConsumerAddrsToPrune) GetVscId() uint64 { return 0 } -func (m *ConsumerAddrsToPrune) GetConsumerAddrs() *ConsumerAddressList { +func (m *ConsumerAddrsToPrune) GetConsumerAddrs() *AddressList { if m != nil { return m.ConsumerAddrs } @@ -1283,14 +1229,12 @@ func init() { proto.RegisterType((*SlashAcks)(nil), "interchain_security.ccv.provider.v1.SlashAcks") proto.RegisterType((*ConsumerAdditionProposals)(nil), "interchain_security.ccv.provider.v1.ConsumerAdditionProposals") proto.RegisterType((*ConsumerRemovalProposals)(nil), "interchain_security.ccv.provider.v1.ConsumerRemovalProposals") + proto.RegisterType((*AddressList)(nil), "interchain_security.ccv.provider.v1.AddressList") proto.RegisterType((*ChannelToChain)(nil), "interchain_security.ccv.provider.v1.ChannelToChain") proto.RegisterType((*VscUnbondingOps)(nil), "interchain_security.ccv.provider.v1.VscUnbondingOps") proto.RegisterType((*UnbondingOp)(nil), "interchain_security.ccv.provider.v1.UnbondingOp") proto.RegisterType((*InitTimeoutTimestamp)(nil), "interchain_security.ccv.provider.v1.InitTimeoutTimestamp") proto.RegisterType((*VscSendTimestamp)(nil), "interchain_security.ccv.provider.v1.VscSendTimestamp") - proto.RegisterType((*ConsumerConsAddress)(nil), "interchain_security.ccv.provider.v1.ConsumerConsAddress") - proto.RegisterType((*ProviderConsAddress)(nil), "interchain_security.ccv.provider.v1.ProviderConsAddress") - proto.RegisterType((*ConsumerAddressList)(nil), "interchain_security.ccv.provider.v1.ConsumerAddressList") proto.RegisterType((*KeyAssignmentReplacement)(nil), "interchain_security.ccv.provider.v1.KeyAssignmentReplacement") proto.RegisterType((*ValidatorConsumerPubKey)(nil), "interchain_security.ccv.provider.v1.ValidatorConsumerPubKey") proto.RegisterType((*ValidatorByConsumerAddr)(nil), "interchain_security.ccv.provider.v1.ValidatorByConsumerAddr") @@ -1302,106 +1246,107 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1570 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6e, 0x1b, 0xc9, - 0x11, 0xd6, 0x90, 0xd4, 0x0f, 0x9b, 0xfa, 0x1d, 0xc9, 0x2b, 0xca, 0x51, 0x28, 0xee, 0xe4, 0x07, - 0x0c, 0x82, 0x1d, 0x42, 0x5a, 0x2c, 0xb0, 0x10, 0x12, 0x2c, 0x24, 0x7a, 0x77, 0xa5, 0x28, 0xbb, - 0xe6, 0x8e, 0x18, 0x05, 0x49, 0x10, 0x0c, 0x7a, 0x7a, 0x5a, 0x64, 0x43, 0x33, 0xd3, 0xe3, 0xee, - 0x9e, 0x59, 0xf3, 0x0d, 0x72, 0x5c, 0x20, 0x97, 0x05, 0x72, 0xf1, 0x25, 0x87, 0x9c, 0xf2, 0x1a, - 0x06, 0x72, 0xf1, 0x21, 0x87, 0x9c, 0x9c, 0x40, 0x7e, 0x03, 0x3f, 0x41, 0xd0, 0x3d, 0xbf, 0xa4, - 0x69, 0x9b, 0x82, 0xbd, 0xb7, 0xe9, 0xea, 0xaa, 0xaf, 0xba, 0xaa, 0xab, 0xbe, 0x6a, 0x12, 0x1c, - 0x91, 0x40, 0x60, 0x86, 0x46, 0x90, 0x04, 0x36, 0xc7, 0x28, 0x62, 0x44, 0x8c, 0xbb, 0x08, 0xc5, - 0xdd, 0x90, 0xd1, 0x98, 0xb8, 0x98, 0x75, 0xe3, 0xc3, 0xfc, 0xdb, 0x0c, 0x19, 0x15, 0x54, 0xff, - 0xc9, 0x0c, 0x1b, 0x13, 0xa1, 0xd8, 0xcc, 0xf5, 0xe2, 0xc3, 0xfb, 0x3b, 0x43, 0x3a, 0xa4, 0x4a, - 0xbf, 0x2b, 0xbf, 0x12, 0xd3, 0xfb, 0x07, 0x43, 0x4a, 0x87, 0x1e, 0xee, 0xaa, 0x95, 0x13, 0x5d, - 0x77, 0x05, 0xf1, 0x31, 0x17, 0xd0, 0x0f, 0x53, 0x85, 0xd6, 0xb4, 0x82, 0x1b, 0x31, 0x28, 0x08, - 0x0d, 0x32, 0x00, 0xe2, 0xa0, 0x2e, 0xa2, 0x0c, 0x77, 0x91, 0x47, 0x70, 0x20, 0xe4, 0xf1, 0x92, - 0xaf, 0x54, 0xa1, 0x2b, 0x15, 0x3c, 0x32, 0x1c, 0x89, 0x44, 0xcc, 0xbb, 0x02, 0x07, 0x2e, 0x66, - 0x3e, 0x49, 0x94, 0x8b, 0x55, 0x6a, 0xb0, 0x5f, 0xda, 0x47, 0x6c, 0x1c, 0x0a, 0xda, 0xbd, 0xc1, - 0x63, 0x9e, 0xee, 0xfe, 0x1c, 0x51, 0xee, 0x53, 0xde, 0xc5, 0x32, 0xb0, 0x00, 0xe1, 0x6e, 0x7c, - 0xe8, 0x60, 0x01, 0x0f, 0x73, 0x41, 0xa2, 0x67, 0xfc, 0x75, 0x09, 0x34, 0x7b, 0x34, 0xe0, 0x91, - 0x8f, 0xd9, 0x89, 0xeb, 0x12, 0x79, 0xe4, 0x3e, 0xa3, 0x21, 0xe5, 0xd0, 0xd3, 0x77, 0xc0, 0xa2, - 0x20, 0xc2, 0xc3, 0x4d, 0xad, 0xad, 0x75, 0xea, 0x56, 0xb2, 0xd0, 0xdb, 0xa0, 0xe1, 0x62, 0x8e, - 0x18, 0x09, 0xa5, 0x72, 0xb3, 0xa2, 0xf6, 0xca, 0x22, 0x7d, 0x0f, 0xac, 0x24, 0x59, 0x26, 0x6e, - 0xb3, 0xaa, 0xb6, 0x97, 0xd5, 0xfa, 0xdc, 0xd5, 0xbf, 0x04, 0xeb, 0x24, 0x20, 0x82, 0x40, 0xcf, - 0x1e, 0x61, 0x19, 0x6d, 0xb3, 0xd6, 0xd6, 0x3a, 0x8d, 0xa3, 0xfb, 0x26, 0x71, 0x90, 0x29, 0x13, - 0x64, 0xa6, 0x69, 0x89, 0x0f, 0xcd, 0x33, 0xa5, 0x71, 0x5a, 0x7b, 0xfa, 0xfc, 0x60, 0xc1, 0x5a, - 0x4b, 0xed, 0x12, 0xa1, 0xfe, 0x21, 0x58, 0x1d, 0xe2, 0x00, 0x73, 0xc2, 0xed, 0x11, 0xe4, 0xa3, - 0xe6, 0x62, 0x5b, 0xeb, 0xac, 0x5a, 0x8d, 0x54, 0x76, 0x06, 0xf9, 0x48, 0x3f, 0x00, 0x0d, 0x87, - 0x04, 0x90, 0x8d, 0x13, 0x8d, 0x25, 0xa5, 0x01, 0x12, 0x91, 0x52, 0xe8, 0x01, 0xc0, 0x43, 0xf8, - 0x6d, 0x60, 0xcb, 0xdb, 0x6c, 0x2e, 0xa7, 0x07, 0x49, 0x6e, 0xd2, 0xcc, 0x6e, 0xd2, 0x1c, 0x64, - 0x57, 0x7d, 0xba, 0x22, 0x0f, 0xf2, 0xdd, 0x7f, 0x0f, 0x34, 0xab, 0xae, 0xec, 0xe4, 0x8e, 0xfe, - 0x35, 0xd8, 0x8c, 0x02, 0x87, 0x06, 0x2e, 0x09, 0x86, 0x76, 0x88, 0x19, 0xa1, 0x6e, 0x73, 0x45, - 0x41, 0xed, 0xbd, 0x02, 0xf5, 0x20, 0x2d, 0x8a, 0x04, 0xe9, 0x7b, 0x89, 0xb4, 0x91, 0x1b, 0xf7, - 0x95, 0xad, 0xfe, 0x0d, 0xd0, 0x11, 0x8a, 0xd5, 0x91, 0x68, 0x24, 0x32, 0xc4, 0xfa, 0xfc, 0x88, - 0x9b, 0x08, 0xc5, 0x83, 0xc4, 0x3a, 0x85, 0xfc, 0x13, 0xd8, 0x15, 0x0c, 0x06, 0xfc, 0x1a, 0xb3, - 0x69, 0x5c, 0x30, 0x3f, 0xee, 0xbd, 0x0c, 0x63, 0x12, 0xfc, 0x0c, 0xb4, 0x51, 0x5a, 0x40, 0x36, - 0xc3, 0x2e, 0xe1, 0x82, 0x11, 0x27, 0x92, 0xb6, 0xf6, 0x35, 0x83, 0x48, 0xd5, 0x48, 0x43, 0x15, - 0x41, 0x2b, 0xd3, 0xb3, 0x26, 0xd4, 0xbe, 0x48, 0xb5, 0xf4, 0x87, 0xe0, 0xa7, 0x8e, 0x47, 0xd1, - 0x0d, 0x97, 0x87, 0xb3, 0x27, 0x90, 0x94, 0x6b, 0x9f, 0x70, 0x2e, 0xd1, 0x56, 0xdb, 0x5a, 0xa7, - 0x6a, 0x7d, 0x98, 0xe8, 0xf6, 0x31, 0x7b, 0x50, 0xd2, 0x1c, 0x94, 0x14, 0xf5, 0x8f, 0x80, 0x3e, - 0x22, 0x5c, 0x50, 0x46, 0x10, 0xf4, 0x6c, 0x1c, 0x08, 0x46, 0x30, 0x6f, 0xae, 0x29, 0xf3, 0xad, - 0x62, 0xe7, 0xf3, 0x64, 0xe3, 0x78, 0xe5, 0x2f, 0x4f, 0x0e, 0x16, 0xbe, 0x7f, 0x72, 0xb0, 0x60, - 0xfc, 0x53, 0x03, 0xbb, 0xbd, 0xfc, 0xb0, 0x3e, 0x8d, 0xa1, 0xf7, 0x43, 0x36, 0xc5, 0x09, 0xa8, - 0x73, 0x41, 0xc3, 0xa4, 0x0c, 0x6b, 0x77, 0x28, 0xc3, 0x15, 0x69, 0x26, 0x37, 0x8c, 0xbf, 0x69, - 0x60, 0xe7, 0xf3, 0x47, 0x11, 0x89, 0x29, 0x82, 0xef, 0xa5, 0x87, 0x2f, 0xc0, 0x1a, 0x2e, 0xe1, - 0xf1, 0x66, 0xb5, 0x5d, 0xed, 0x34, 0x8e, 0x7e, 0x66, 0x26, 0xc4, 0x62, 0xe6, 0x3c, 0x92, 0x12, - 0x8b, 0x59, 0xf6, 0x6e, 0x4d, 0xda, 0x1a, 0x7f, 0xaf, 0x80, 0xcd, 0x2f, 0x3d, 0xea, 0x40, 0xef, - 0xd2, 0x83, 0x7c, 0x24, 0x13, 0x3e, 0x96, 0x51, 0x33, 0x9c, 0x56, 0xba, 0x3a, 0xdd, 0xdc, 0x51, - 0x4b, 0x33, 0xd5, 0x7b, 0x9f, 0x81, 0xad, 0xbc, 0xf6, 0xf2, 0xe4, 0xaa, 0x60, 0x4e, 0xb7, 0x6f, - 0x9f, 0x1f, 0x6c, 0x64, 0x77, 0xd8, 0x53, 0x89, 0x7e, 0x60, 0x6d, 0xa0, 0x09, 0x81, 0xab, 0xb7, - 0x40, 0x83, 0x38, 0xc8, 0xe6, 0xf8, 0x91, 0x1d, 0x44, 0xbe, 0xba, 0x97, 0x9a, 0x55, 0x27, 0x0e, - 0xba, 0xc4, 0x8f, 0xbe, 0x8e, 0x7c, 0xdd, 0x07, 0x1f, 0x64, 0xc3, 0xc1, 0x8e, 0xa1, 0x67, 0x4b, - 0x7b, 0x1b, 0xba, 0x2e, 0x4b, 0xaf, 0xe9, 0x53, 0x73, 0x8e, 0x99, 0x62, 0xf6, 0xd3, 0x6f, 0x79, - 0x9c, 0x13, 0xd7, 0x65, 0x98, 0x73, 0x6b, 0x3b, 0x53, 0xb8, 0x82, 0x5e, 0x26, 0x37, 0x5e, 0xd6, - 0xc0, 0x52, 0x1f, 0x32, 0xe8, 0x73, 0x7d, 0x00, 0x36, 0x04, 0xf6, 0x43, 0x0f, 0x0a, 0x6c, 0x27, - 0x8c, 0x98, 0xe6, 0xe8, 0x97, 0x8a, 0x29, 0xcb, 0x93, 0xc2, 0x2c, 0xcd, 0x86, 0xf8, 0xd0, 0xec, - 0x29, 0xe9, 0xa5, 0x80, 0x02, 0x5b, 0xeb, 0x19, 0x46, 0x22, 0xd4, 0x3f, 0x05, 0x4d, 0xc1, 0x22, - 0x2e, 0x0a, 0xae, 0x2a, 0x9a, 0x34, 0x29, 0x82, 0x0f, 0xb2, 0xfd, 0xa4, 0xbd, 0xf3, 0xe6, 0x9c, - 0x4d, 0x4b, 0xd5, 0x77, 0xa1, 0xa5, 0x4b, 0xb0, 0x2d, 0x39, 0x7d, 0x1a, 0xb3, 0x36, 0x3f, 0xe6, - 0x96, 0xb4, 0x9f, 0x04, 0xfd, 0x06, 0xe8, 0x31, 0x47, 0xd3, 0x98, 0x8b, 0x77, 0x38, 0x67, 0xcc, - 0xd1, 0x24, 0xa4, 0x0b, 0xf6, 0xb9, 0x2c, 0x5b, 0xdb, 0xc7, 0x42, 0x91, 0x5c, 0xe8, 0xe1, 0x80, - 0xf0, 0x51, 0x06, 0xbe, 0x34, 0x3f, 0xf8, 0x9e, 0x02, 0xfa, 0x4a, 0xe2, 0x58, 0x19, 0x4c, 0xea, - 0xa5, 0x07, 0x5a, 0xb3, 0xbd, 0xe4, 0x17, 0xb4, 0xac, 0x2e, 0xe8, 0x47, 0x33, 0x20, 0xf2, 0x5b, - 0x3a, 0x02, 0xf7, 0x7c, 0xf8, 0xd8, 0x16, 0x23, 0x46, 0x85, 0xf0, 0xb0, 0x6b, 0x87, 0x10, 0xdd, - 0x60, 0xc1, 0xd5, 0x44, 0xaa, 0x5a, 0xdb, 0x3e, 0x7c, 0x3c, 0xc8, 0xf6, 0xfa, 0xc9, 0x96, 0xe1, - 0x80, 0xad, 0x33, 0x18, 0xb8, 0x7c, 0x04, 0x6f, 0xf0, 0x57, 0x58, 0x40, 0x17, 0x0a, 0xa8, 0x7f, - 0x5c, 0x2a, 0xfc, 0x6b, 0x8c, 0xed, 0x90, 0x52, 0x2f, 0x29, 0xfc, 0x84, 0x47, 0xf2, 0xf2, 0xfd, - 0x02, 0xe3, 0x3e, 0xa5, 0x9e, 0x2c, 0x5f, 0xbd, 0x09, 0x96, 0x63, 0xcc, 0x78, 0x51, 0x4c, 0xd9, - 0xd2, 0xf8, 0x05, 0xa8, 0xab, 0xce, 0x3f, 0x41, 0x37, 0x5c, 0xdf, 0x07, 0x75, 0x98, 0x74, 0x01, - 0xe6, 0x4d, 0xad, 0x5d, 0xed, 0xd4, 0xad, 0x42, 0x60, 0x08, 0xb0, 0xf7, 0xba, 0x07, 0x09, 0xd7, - 0x7f, 0x0f, 0x96, 0x43, 0xac, 0xa6, 0xa5, 0x32, 0x6c, 0x1c, 0xfd, 0x7a, 0xae, 0x06, 0x7c, 0x1d, - 0xa0, 0x95, 0xa1, 0x19, 0xac, 0x78, 0x06, 0x4d, 0x11, 0x3e, 0xd7, 0xaf, 0xa6, 0x9d, 0xfe, 0xea, - 0x4e, 0x4e, 0xa7, 0xf0, 0x0a, 0x9f, 0xbf, 0x01, 0xeb, 0xbd, 0x11, 0x0c, 0x02, 0xec, 0x0d, 0xa8, - 0x22, 0x24, 0xfd, 0xc7, 0x00, 0xa0, 0x44, 0x22, 0x89, 0x2c, 0xc9, 0x74, 0x3d, 0x95, 0x9c, 0xbb, - 0x13, 0x23, 0xa4, 0x32, 0x31, 0x42, 0x0c, 0x0b, 0x6c, 0x5c, 0x71, 0xf4, 0xbb, 0xec, 0x2d, 0xf1, - 0x30, 0xe4, 0xfa, 0x3d, 0xb0, 0x24, 0x3b, 0x21, 0x05, 0xaa, 0x59, 0x8b, 0x31, 0x47, 0xe7, 0xae, - 0xde, 0x29, 0xbf, 0x57, 0x68, 0x68, 0x13, 0x97, 0x37, 0x2b, 0xed, 0x6a, 0xa7, 0x66, 0xad, 0x47, - 0x85, 0xf9, 0xb9, 0xcb, 0x8d, 0x3f, 0x80, 0x46, 0x09, 0x50, 0x5f, 0x07, 0x95, 0x1c, 0xab, 0x42, - 0x5c, 0xfd, 0x18, 0xec, 0x15, 0x40, 0x93, 0x34, 0x9c, 0x20, 0xd6, 0xad, 0xdd, 0x5c, 0x61, 0x82, - 0x89, 0xb9, 0xf1, 0x10, 0xec, 0x9c, 0x17, 0xad, 0x9b, 0x93, 0xfc, 0x44, 0x84, 0xda, 0xe4, 0x90, - 0xdc, 0x07, 0xf5, 0xfc, 0xd1, 0xad, 0xa2, 0xaf, 0x59, 0x85, 0xc0, 0xf0, 0xc1, 0xe6, 0x15, 0x47, - 0x97, 0x38, 0x70, 0x0b, 0xb0, 0xd7, 0x24, 0xe0, 0x74, 0x1a, 0x68, 0xee, 0x47, 0x5f, 0xe1, 0xee, - 0x13, 0xb0, 0x9d, 0x47, 0x54, 0x90, 0xba, 0x6c, 0x80, 0xb4, 0x90, 0x95, 0xcb, 0x55, 0x2b, 0x5b, - 0x1e, 0xd7, 0xd4, 0xbb, 0xe2, 0x13, 0xb0, 0x3d, 0x63, 0x16, 0xbc, 0xd5, 0xcc, 0x2f, 0xbc, 0xa5, - 0x26, 0xbf, 0x25, 0x5c, 0xe8, 0x57, 0xd3, 0x7d, 0x34, 0xef, 0x3c, 0x9a, 0x71, 0xf4, 0x72, 0x07, - 0xfe, 0x4b, 0x03, 0xcd, 0x0b, 0x3c, 0x3e, 0xe1, 0x9c, 0x0c, 0x03, 0x1f, 0x07, 0x42, 0xf2, 0x0c, - 0x44, 0x58, 0x7e, 0xea, 0x7f, 0x06, 0x6b, 0x39, 0x31, 0xe4, 0x7c, 0xf0, 0x2e, 0x83, 0x70, 0x35, - 0x53, 0x50, 0x14, 0x72, 0x0c, 0x40, 0xc8, 0x70, 0x6c, 0x23, 0xfb, 0x06, 0x8f, 0xd3, 0xdb, 0xd9, - 0x2f, 0x0f, 0xb8, 0xe4, 0xa7, 0x8e, 0xd9, 0x8f, 0x1c, 0x8f, 0xa0, 0x0b, 0x3c, 0xb6, 0x56, 0xa4, - 0x7e, 0xef, 0x02, 0x8f, 0xe5, 0x53, 0x27, 0xa4, 0xdf, 0x62, 0xa6, 0xa6, 0x52, 0xd5, 0x4a, 0x16, - 0xc6, 0xbf, 0x35, 0xb0, 0x7b, 0x05, 0x3d, 0xe2, 0x42, 0x41, 0x59, 0x16, 0x79, 0x3f, 0x72, 0xa4, - 0xc5, 0x1b, 0xca, 0xed, 0x95, 0x38, 0x2b, 0xef, 0x35, 0xce, 0xcf, 0xc0, 0x6a, 0xde, 0x32, 0x32, - 0xd2, 0xea, 0x1c, 0x91, 0x36, 0x32, 0x8b, 0x0b, 0x3c, 0x36, 0x5e, 0x96, 0xc3, 0x3a, 0x1d, 0x97, - 0xeb, 0xe3, 0x2d, 0x61, 0xe5, 0x7e, 0xef, 0x1c, 0xd6, 0xac, 0xba, 0xc9, 0xc3, 0x50, 0x9e, 0x5f, - 0xc9, 0x5a, 0xf5, 0x7d, 0x66, 0xcd, 0xf8, 0x87, 0x06, 0x76, 0xca, 0x91, 0xf2, 0x01, 0xed, 0xb3, - 0x28, 0xc0, 0x6f, 0x8a, 0xb8, 0x60, 0x81, 0x4a, 0x99, 0x05, 0x6c, 0xb0, 0x3e, 0x91, 0x08, 0x7e, - 0xa7, 0xa3, 0xce, 0x68, 0x47, 0x6b, 0xad, 0x9c, 0x09, 0x7e, 0x3a, 0x78, 0x7a, 0xdb, 0xd2, 0x9e, - 0xdd, 0xb6, 0xb4, 0xff, 0xdd, 0xb6, 0xb4, 0xef, 0x5e, 0xb4, 0x16, 0x9e, 0xbd, 0x68, 0x2d, 0xfc, - 0xe7, 0x45, 0x6b, 0xe1, 0x8f, 0xc7, 0x43, 0x22, 0x46, 0x91, 0x63, 0x22, 0xea, 0x77, 0xd3, 0x9f, - 0xe9, 0x85, 0xcf, 0x8f, 0xf2, 0x7f, 0x33, 0x1e, 0x4f, 0xfe, 0x9f, 0x21, 0xc6, 0x21, 0xe6, 0xce, - 0x92, 0x62, 0xa8, 0x8f, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x0a, 0x32, 0xf6, 0x00, 0x11, - 0x00, 0x00, + // 1598 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4b, 0x73, 0xdc, 0xc6, + 0x11, 0x26, 0xb8, 0x7c, 0xed, 0x2c, 0x1f, 0x12, 0x44, 0x59, 0x4b, 0x85, 0x59, 0xae, 0xe0, 0xc4, + 0xc5, 0x94, 0xcb, 0xd8, 0x90, 0xbe, 0xa4, 0x54, 0x71, 0xb9, 0xc8, 0x95, 0x65, 0xd1, 0x8c, 0xad, + 0x35, 0xc8, 0x50, 0x95, 0xe4, 0x80, 0x1a, 0x0c, 0x5a, 0xbb, 0x53, 0x04, 0x30, 0xd0, 0xcc, 0x00, + 0xd2, 0x5e, 0x72, 0xce, 0xd1, 0xb9, 0xb9, 0x92, 0x8b, 0xf3, 0x0b, 0xf2, 0x37, 0x7c, 0xf4, 0x31, + 0x27, 0x3b, 0x45, 0x1d, 0x72, 0xc8, 0x9f, 0x48, 0xcd, 0xe0, 0xcd, 0x87, 0xb2, 0xaa, 0xc4, 0x37, + 0xcc, 0x4c, 0xf7, 0xd7, 0xdd, 0xd3, 0xdd, 0x5f, 0x0f, 0xd0, 0x3e, 0x8d, 0x24, 0x70, 0x32, 0xc1, + 0x34, 0x72, 0x05, 0x90, 0x84, 0x53, 0x39, 0x1d, 0x10, 0x92, 0x0e, 0x62, 0xce, 0x52, 0xea, 0x03, + 0x1f, 0xa4, 0x7b, 0xe5, 0xb7, 0x1d, 0x73, 0x26, 0x99, 0xf9, 0xee, 0x35, 0x3a, 0x36, 0x21, 0xa9, + 0x5d, 0xca, 0xa5, 0x7b, 0xf7, 0x37, 0xc7, 0x6c, 0xcc, 0xb4, 0xfc, 0x40, 0x7d, 0x65, 0xaa, 0xf7, + 0x77, 0xc6, 0x8c, 0x8d, 0x03, 0x18, 0xe8, 0x95, 0x97, 0x3c, 0x1f, 0x48, 0x1a, 0x82, 0x90, 0x38, + 0x8c, 0x73, 0x81, 0xde, 0x65, 0x01, 0x3f, 0xe1, 0x58, 0x52, 0x16, 0x15, 0x00, 0xd4, 0x23, 0x03, + 0xc2, 0x38, 0x0c, 0x48, 0x40, 0x21, 0x92, 0xca, 0xbd, 0xec, 0x2b, 0x17, 0x18, 0x28, 0x81, 0x80, + 0x8e, 0x27, 0x32, 0xdb, 0x16, 0x03, 0x09, 0x91, 0x0f, 0x3c, 0xa4, 0x99, 0x70, 0xb5, 0xca, 0x15, + 0xb6, 0x6b, 0xe7, 0x84, 0x4f, 0x63, 0xc9, 0x06, 0xe7, 0x30, 0x15, 0xf9, 0xe9, 0x7b, 0x84, 0x89, + 0x90, 0x89, 0x01, 0xa8, 0xc0, 0x22, 0x02, 0x83, 0x74, 0xcf, 0x03, 0x89, 0xf7, 0xca, 0x8d, 0xc2, + 0xef, 0x5c, 0xce, 0xc3, 0xa2, 0x92, 0x21, 0x8c, 0xe6, 0x7e, 0x5b, 0x3f, 0x2c, 0xa1, 0xee, 0x90, + 0x45, 0x22, 0x09, 0x81, 0x1f, 0xf8, 0x3e, 0x55, 0x21, 0x8d, 0x38, 0x8b, 0x99, 0xc0, 0x81, 0xb9, + 0x89, 0x16, 0x25, 0x95, 0x01, 0x74, 0x8d, 0xbe, 0xb1, 0xdb, 0x76, 0xb2, 0x85, 0xd9, 0x47, 0x1d, + 0x1f, 0x04, 0xe1, 0x34, 0x56, 0xc2, 0xdd, 0x79, 0x7d, 0x56, 0xdf, 0x32, 0xb7, 0xd0, 0x4a, 0x96, + 0x05, 0xea, 0x77, 0x5b, 0xfa, 0x78, 0x59, 0xaf, 0x8f, 0x7c, 0xf3, 0x53, 0xb4, 0x4e, 0x23, 0x2a, + 0x29, 0x0e, 0xdc, 0x09, 0xa8, 0xdb, 0xe8, 0x2e, 0xf4, 0x8d, 0xdd, 0xce, 0xfe, 0x7d, 0x9b, 0x7a, + 0xc4, 0x56, 0x17, 0x68, 0xe7, 0xd7, 0x96, 0xee, 0xd9, 0x4f, 0xb4, 0xc4, 0xe1, 0xc2, 0xb7, 0xdf, + 0xef, 0xcc, 0x39, 0x6b, 0xb9, 0x5e, 0xb6, 0x69, 0x3e, 0x40, 0xab, 0x63, 0x88, 0x40, 0x50, 0xe1, + 0x4e, 0xb0, 0x98, 0x74, 0x17, 0xfb, 0xc6, 0xee, 0xaa, 0xd3, 0xc9, 0xf7, 0x9e, 0x60, 0x31, 0x31, + 0x77, 0x50, 0xc7, 0xa3, 0x11, 0xe6, 0xd3, 0x4c, 0x62, 0x49, 0x4b, 0xa0, 0x6c, 0x4b, 0x0b, 0x0c, + 0x11, 0x12, 0x31, 0x7e, 0x19, 0xb9, 0x2a, 0xdb, 0xdd, 0xe5, 0xdc, 0x91, 0x2c, 0xd3, 0x76, 0x91, + 0x69, 0xfb, 0xb4, 0x28, 0x85, 0xc3, 0x15, 0xe5, 0xc8, 0x57, 0x3f, 0xec, 0x18, 0x4e, 0x5b, 0xeb, + 0xa9, 0x13, 0xf3, 0x0b, 0x74, 0x2b, 0x89, 0x3c, 0x16, 0xf9, 0x34, 0x1a, 0xbb, 0x31, 0x70, 0xca, + 0xfc, 0xee, 0x8a, 0x86, 0xda, 0xba, 0x02, 0xf5, 0x28, 0x2f, 0x9a, 0x0c, 0xe9, 0x6b, 0x85, 0xb4, + 0x51, 0x2a, 0x8f, 0xb4, 0xae, 0xf9, 0x25, 0x32, 0x09, 0x49, 0xb5, 0x4b, 0x2c, 0x91, 0x05, 0x62, + 0x7b, 0x76, 0xc4, 0x5b, 0x84, 0xa4, 0xa7, 0x99, 0x76, 0x0e, 0xf9, 0x07, 0x74, 0x4f, 0x72, 0x1c, + 0x89, 0xe7, 0xc0, 0x2f, 0xe3, 0xa2, 0xd9, 0x71, 0xef, 0x16, 0x18, 0x4d, 0xf0, 0x27, 0xa8, 0x4f, + 0xf2, 0x02, 0x72, 0x39, 0xf8, 0x54, 0x48, 0x4e, 0xbd, 0x44, 0xe9, 0xba, 0xcf, 0x39, 0x26, 0xba, + 0x46, 0x3a, 0xba, 0x08, 0x7a, 0x85, 0x9c, 0xd3, 0x10, 0x7b, 0x9c, 0x4b, 0x99, 0x4f, 0xd1, 0xcf, + 0xbc, 0x80, 0x91, 0x73, 0xa1, 0x9c, 0x73, 0x1b, 0x48, 0xda, 0x74, 0x48, 0x85, 0x50, 0x68, 0xab, + 0x7d, 0x63, 0xb7, 0xe5, 0x3c, 0xc8, 0x64, 0x47, 0xc0, 0x1f, 0xd5, 0x24, 0x4f, 0x6b, 0x82, 0xe6, + 0x07, 0xc8, 0x9c, 0x50, 0x21, 0x19, 0xa7, 0x04, 0x07, 0x2e, 0x44, 0x92, 0x53, 0x10, 0xdd, 0x35, + 0xad, 0x7e, 0xbb, 0x3a, 0xf9, 0x24, 0x3b, 0x30, 0x3f, 0x43, 0x0f, 0x6e, 0x34, 0xea, 0x92, 0x09, + 0x8e, 0x22, 0x08, 0xba, 0xeb, 0x3a, 0x94, 0x1d, 0xff, 0x06, 0x9b, 0xc3, 0x4c, 0xec, 0xe1, 0xca, + 0x9f, 0xbe, 0xd9, 0x99, 0xfb, 0xfa, 0x9b, 0x9d, 0x39, 0xeb, 0xef, 0x06, 0xba, 0x37, 0x2c, 0x03, + 0x0f, 0x59, 0x8a, 0x83, 0x1f, 0xb3, 0xc1, 0x0e, 0x50, 0x5b, 0x48, 0x16, 0x67, 0x25, 0xbd, 0xf0, + 0x16, 0x25, 0xbd, 0xa2, 0xd4, 0xd4, 0x81, 0xf5, 0x57, 0x03, 0x6d, 0x7e, 0xf2, 0x22, 0xa1, 0x29, + 0x23, 0xf8, 0xff, 0xc2, 0x07, 0xc7, 0x68, 0x0d, 0x6a, 0x78, 0xa2, 0xdb, 0xea, 0xb7, 0x76, 0x3b, + 0xfb, 0x3f, 0xb7, 0x33, 0x72, 0xb2, 0x4b, 0xce, 0xca, 0x09, 0xca, 0xae, 0x5b, 0x77, 0x9a, 0xba, + 0xd6, 0xbf, 0x0d, 0x74, 0xeb, 0xd3, 0x80, 0x79, 0x38, 0x38, 0x09, 0xb0, 0x98, 0xa8, 0xe4, 0x4d, + 0x55, 0xd4, 0x1c, 0xf2, 0xae, 0xd1, 0xde, 0xcd, 0x1c, 0xb5, 0x52, 0xd3, 0x7d, 0xfc, 0x31, 0xba, + 0x5d, 0xd6, 0x71, 0x79, 0xb9, 0x3a, 0x98, 0xc3, 0x3b, 0x17, 0xdf, 0xef, 0x6c, 0x14, 0x39, 0x1c, + 0xea, 0x8b, 0x7e, 0xe4, 0x6c, 0x90, 0xc6, 0x86, 0x6f, 0xf6, 0x50, 0x87, 0x7a, 0xc4, 0x15, 0xf0, + 0xc2, 0x8d, 0x92, 0x50, 0xe7, 0x65, 0xc1, 0x69, 0x53, 0x8f, 0x9c, 0xc0, 0x8b, 0x2f, 0x92, 0xd0, + 0xfc, 0x10, 0xbd, 0x53, 0x0c, 0x22, 0x37, 0xc5, 0x81, 0xab, 0xf4, 0x5d, 0xec, 0xfb, 0x5c, 0xa7, + 0x69, 0xd5, 0xb9, 0x53, 0x9c, 0x9e, 0xe1, 0x40, 0x19, 0x3b, 0xf0, 0x7d, 0x6e, 0xfd, 0x6b, 0x11, + 0x2d, 0x8d, 0x30, 0xc7, 0xa1, 0x30, 0x4f, 0xd1, 0x86, 0x84, 0x30, 0x0e, 0xb0, 0x04, 0x37, 0xe3, + 0xc8, 0x3c, 0xd2, 0xf7, 0x35, 0x77, 0xd6, 0x67, 0x8b, 0x5d, 0x9b, 0x26, 0xe9, 0x9e, 0x3d, 0xd4, + 0xbb, 0x27, 0x12, 0x4b, 0x70, 0xd6, 0x0b, 0x8c, 0x6c, 0xd3, 0xfc, 0x15, 0xea, 0x4a, 0x9e, 0x08, + 0x59, 0xb1, 0x57, 0xd5, 0xb6, 0x59, 0x2a, 0xdf, 0x29, 0xce, 0xb3, 0x86, 0x2f, 0xdb, 0xf5, 0x7a, + 0xa2, 0x6a, 0xfd, 0x2f, 0x44, 0x75, 0x82, 0xee, 0x28, 0x96, 0xbf, 0x8c, 0xb9, 0x30, 0x3b, 0xe6, + 0x6d, 0xa5, 0xdf, 0x04, 0xfd, 0x12, 0x99, 0xa9, 0x20, 0x97, 0x31, 0x17, 0xdf, 0xc2, 0xcf, 0x54, + 0x90, 0x26, 0xa4, 0x8f, 0xb6, 0x85, 0x2a, 0x3e, 0x37, 0x04, 0xa9, 0x69, 0x2f, 0x0e, 0x20, 0xa2, + 0x62, 0x52, 0x80, 0x2f, 0xcd, 0x0e, 0xbe, 0xa5, 0x81, 0x3e, 0x57, 0x38, 0x4e, 0x01, 0x93, 0x5b, + 0x19, 0xa2, 0xde, 0xf5, 0x56, 0xca, 0x04, 0x2d, 0xeb, 0x04, 0xfd, 0xe4, 0x1a, 0x88, 0x32, 0x4b, + 0xfb, 0xe8, 0x6e, 0x88, 0x5f, 0xb9, 0x72, 0xc2, 0x99, 0x94, 0x01, 0xf8, 0x6e, 0x8c, 0xc9, 0x39, + 0x48, 0xa1, 0x67, 0x54, 0xcb, 0xb9, 0x13, 0xe2, 0x57, 0xa7, 0xc5, 0xd9, 0x28, 0x3b, 0x32, 0x05, + 0x7a, 0xaf, 0x46, 0xe9, 0x2f, 0x31, 0xf7, 0x5d, 0x1f, 0x22, 0x16, 0xba, 0x1c, 0xc6, 0x8a, 0xf7, + 0x70, 0xc6, 0xee, 0x00, 0xe5, 0x58, 0xca, 0x1b, 0x59, 0xbd, 0x32, 0xca, 0x26, 0x1e, 0x32, 0x1a, + 0xe5, 0xb3, 0xdb, 0xaa, 0x98, 0x5f, 0xa1, 0x3d, 0x52, 0x60, 0x4e, 0x0d, 0xeb, 0x31, 0x80, 0xe5, + 0xa1, 0xdb, 0x4f, 0x70, 0xe4, 0x8b, 0x09, 0x3e, 0x87, 0xcf, 0x41, 0x62, 0x1f, 0x4b, 0xdc, 0xe8, + 0x99, 0xe7, 0x00, 0x6e, 0xcc, 0x58, 0x90, 0xf5, 0x4c, 0x46, 0x41, 0x65, 0xcf, 0x3c, 0x06, 0x18, + 0x31, 0x16, 0xa8, 0x9e, 0x31, 0xbb, 0x68, 0x39, 0x05, 0x2e, 0xaa, 0x0a, 0x2e, 0x96, 0xd6, 0x2f, + 0x50, 0x5b, 0x93, 0xc6, 0x01, 0x39, 0x17, 0xe6, 0x36, 0x6a, 0x2b, 0x24, 0x10, 0x02, 0x44, 0xd7, + 0xe8, 0xb7, 0x76, 0xdb, 0x4e, 0xb5, 0x61, 0x49, 0xb4, 0x75, 0xd3, 0xbb, 0x48, 0x98, 0xcf, 0xd0, + 0x72, 0x0c, 0x7a, 0x68, 0x6b, 0xc5, 0xce, 0xfe, 0x47, 0xf6, 0x0c, 0x6f, 0x4f, 0xfb, 0x26, 0x40, + 0xa7, 0x40, 0xb3, 0x78, 0xf5, 0x1a, 0xbb, 0x34, 0x2b, 0x84, 0x79, 0x76, 0xd9, 0xe8, 0xaf, 0xdf, + 0xca, 0xe8, 0x25, 0xbc, 0xca, 0xe6, 0xfb, 0xa8, 0x73, 0x90, 0x85, 0xfd, 0x1b, 0x2a, 0xe4, 0xd5, + 0x6b, 0x59, 0xad, 0x5f, 0xcb, 0x67, 0x68, 0x3d, 0x1f, 0x71, 0xa7, 0x4c, 0x13, 0x9f, 0xf9, 0x53, + 0x84, 0xf2, 0xd9, 0xa8, 0x08, 0x33, 0x4b, 0x4b, 0x3b, 0xdf, 0x39, 0xf2, 0x1b, 0xa3, 0x6a, 0xbe, + 0x31, 0xaa, 0x2c, 0x07, 0x6d, 0x9c, 0x09, 0xf2, 0xdb, 0xe2, 0xfd, 0xf3, 0x34, 0x16, 0xe6, 0x5d, + 0xb4, 0xa4, 0x7a, 0x35, 0x07, 0x5a, 0x70, 0x16, 0x53, 0x41, 0x8e, 0x7c, 0x73, 0xb7, 0xfe, 0xc6, + 0x62, 0xb1, 0x4b, 0x7d, 0xd1, 0x9d, 0xef, 0xb7, 0x76, 0x17, 0x9c, 0xf5, 0xa4, 0x52, 0x3f, 0xf2, + 0x85, 0xf5, 0x3b, 0xd4, 0xa9, 0x01, 0x9a, 0xeb, 0x68, 0xbe, 0xc4, 0x9a, 0xa7, 0xbe, 0xf9, 0x10, + 0x6d, 0x55, 0x40, 0x4d, 0xba, 0xcf, 0x10, 0xdb, 0xce, 0xbd, 0x52, 0xa0, 0xc1, 0xf8, 0xc2, 0x7a, + 0x8a, 0x36, 0x8f, 0x2a, 0x72, 0x29, 0x87, 0x49, 0x23, 0x42, 0xa3, 0x39, 0x8c, 0xb7, 0x51, 0xbb, + 0xfc, 0x91, 0xd0, 0xd1, 0x2f, 0x38, 0xd5, 0x86, 0x15, 0xa2, 0x5b, 0x67, 0x82, 0x9c, 0x40, 0xe4, + 0x57, 0x60, 0x37, 0x5c, 0xc0, 0xe1, 0x65, 0xa0, 0x99, 0x1f, 0xaa, 0x95, 0xb9, 0x3f, 0x1b, 0xa8, + 0x7b, 0x0c, 0xd3, 0x03, 0x21, 0xe8, 0x38, 0x0a, 0x21, 0x92, 0x8a, 0x2c, 0x30, 0x01, 0xf5, 0x69, + 0xbe, 0x8b, 0xd6, 0xca, 0x46, 0x2b, 0xfb, 0x6b, 0xd5, 0x59, 0x2d, 0x36, 0x75, 0x63, 0x3d, 0x44, + 0x28, 0xe6, 0x90, 0xba, 0xc4, 0x3d, 0x87, 0x69, 0xee, 0xc6, 0x76, 0x7d, 0xd6, 0x64, 0xff, 0x29, + 0xf6, 0x28, 0xf1, 0x02, 0x4a, 0x8e, 0x61, 0xea, 0xac, 0x28, 0xf9, 0xe1, 0x31, 0x4c, 0xd5, 0xdb, + 0x21, 0x66, 0x2f, 0x81, 0xeb, 0x01, 0xd1, 0x72, 0xb2, 0x85, 0xf5, 0x17, 0x03, 0xdd, 0x3b, 0xc3, + 0x01, 0xf5, 0xb1, 0x64, 0xbc, 0xb8, 0xef, 0x51, 0xe2, 0x29, 0x8d, 0x37, 0xdc, 0xeb, 0x15, 0x6f, + 0xe7, 0xaf, 0xf1, 0xf6, 0x63, 0xb4, 0x5a, 0x66, 0x58, 0xf9, 0xdb, 0x9a, 0xc1, 0xdf, 0x4e, 0xa1, + 0x71, 0x0c, 0x53, 0xeb, 0x8f, 0x35, 0xdf, 0x0e, 0xa7, 0xb5, 0xe6, 0xe5, 0xff, 0xc5, 0xb7, 0xd2, + 0x6c, 0xdd, 0x37, 0x52, 0xd7, 0xbf, 0x12, 0x40, 0xeb, 0x6a, 0x00, 0xd6, 0xdf, 0x0c, 0xb4, 0x59, + 0xb7, 0x2a, 0x4e, 0xd9, 0x88, 0x27, 0x11, 0xbc, 0xc9, 0x7a, 0x55, 0x3f, 0xf3, 0xf5, 0xfa, 0x79, + 0x86, 0xd6, 0x1b, 0x4e, 0x89, 0xfc, 0x36, 0x7e, 0x39, 0x13, 0x85, 0xd4, 0xe8, 0xc1, 0x59, 0xab, + 0xc7, 0x21, 0x0e, 0x9f, 0x7d, 0x7b, 0xd1, 0x33, 0xbe, 0xbb, 0xe8, 0x19, 0xff, 0xbc, 0xe8, 0x19, + 0x5f, 0xbd, 0xee, 0xcd, 0x7d, 0xf7, 0xba, 0x37, 0xf7, 0x8f, 0xd7, 0xbd, 0xb9, 0xdf, 0x7f, 0x34, + 0xa6, 0x72, 0x92, 0x78, 0x36, 0x61, 0xe1, 0x20, 0xff, 0x09, 0xad, 0x6c, 0x7d, 0x50, 0xfe, 0xd3, + 0xa7, 0xfb, 0x83, 0x57, 0xcd, 0x1f, 0x7b, 0x39, 0x8d, 0x41, 0x78, 0x4b, 0xba, 0xac, 0x3f, 0xfc, + 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x4c, 0xb0, 0x24, 0x09, 0x10, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -1424,6 +1369,13 @@ func (m *ConsumerAdditionProposal) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.DistributionTransmissionChannel) > 0 { + i -= len(m.DistributionTransmissionChannel) + copy(dAtA[i:], m.DistributionTransmissionChannel) + i = encodeVarintProvider(dAtA, i, uint64(len(m.DistributionTransmissionChannel))) + i-- + dAtA[i] = 0x72 + } if m.HistoricalEntries != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.HistoricalEntries)) i-- @@ -1644,15 +1596,10 @@ func (m *GlobalSlashEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ProviderValConsAddr != nil { - { - size, err := m.ProviderValConsAddr.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } + if len(m.ProviderValConsAddr) > 0 { + i -= len(m.ProviderValConsAddr) + copy(dAtA[i:], m.ProviderValConsAddr) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ProviderValConsAddr))) i-- dAtA[i] = 0x22 } @@ -1668,12 +1615,12 @@ func (m *GlobalSlashEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.RecvTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.RecvTime):]) - if err8 != nil { - return 0, err8 + n7, err7 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.RecvTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.RecvTime):]) + if err7 != nil { + return 0, err7 } - i -= n8 - i = encodeVarintProvider(dAtA, i, uint64(n8)) + i -= n7 + i = encodeVarintProvider(dAtA, i, uint64(n7)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -1699,6 +1646,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.ConsumerRewardDenomRegistrationFee.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProvider(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a if m.MaxThrottledPackets != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.MaxThrottledPackets)) i-- @@ -1908,6 +1865,38 @@ func (m *ConsumerRemovalProposals) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *AddressList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddressList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Addresses) > 0 { + for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Addresses[iNdEx]) + copy(dAtA[i:], m.Addresses[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Addresses[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *ChannelToChain) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2099,7 +2088,7 @@ func (m *VscSendTimestamp) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ConsumerConsAddress) Marshal() (dAtA []byte, err error) { +func (m *KeyAssignmentReplacement) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2109,27 +2098,44 @@ func (m *ConsumerConsAddress) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ConsumerConsAddress) MarshalTo(dAtA []byte) (int, error) { +func (m *KeyAssignmentReplacement) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ConsumerConsAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *KeyAssignmentReplacement) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Address) > 0 { - i -= len(m.Address) - copy(dAtA[i:], m.Address) - i = encodeVarintProvider(dAtA, i, uint64(len(m.Address))) + if m.Power != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Power)) + i-- + dAtA[i] = 0x18 + } + if m.PrevCKey != nil { + { + size, err := m.PrevCKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProvider(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ProviderAddr))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ProviderConsAddress) Marshal() (dAtA []byte, err error) { +func (m *ValidatorConsumerPubKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2139,27 +2145,46 @@ func (m *ProviderConsAddress) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ProviderConsAddress) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatorConsumerPubKey) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ProviderConsAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatorConsumerPubKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Address) > 0 { - i -= len(m.Address) - copy(dAtA[i:], m.Address) - i = encodeVarintProvider(dAtA, i, uint64(len(m.Address))) + if m.ConsumerKey != nil { + { + size, err := m.ConsumerKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProvider(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ChainId))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ConsumerAddressList) Marshal() (dAtA []byte, err error) { +func (m *ValidatorByConsumerAddr) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2169,34 +2194,41 @@ func (m *ConsumerAddressList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ConsumerAddressList) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatorByConsumerAddr) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ConsumerAddressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatorByConsumerAddr) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Addresses) > 0 { - for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Addresses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.ConsumerAddr) > 0 { + i -= len(m.ConsumerAddr) + copy(dAtA[i:], m.ConsumerAddr) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ConsumerAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *KeyAssignmentReplacement) Marshal() (dAtA []byte, err error) { +func (m *ConsumerAddrsToPrune) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2206,172 +2238,12 @@ func (m *KeyAssignmentReplacement) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *KeyAssignmentReplacement) MarshalTo(dAtA []byte) (int, error) { +func (m *ConsumerAddrsToPrune) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *KeyAssignmentReplacement) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Power != 0 { - i = encodeVarintProvider(dAtA, i, uint64(m.Power)) - i-- - dAtA[i] = 0x18 - } - if m.PrevCKey != nil { - { - size, err := m.PrevCKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.ProviderAddr != nil { - { - size, err := m.ProviderAddr.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ValidatorConsumerPubKey) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ValidatorConsumerPubKey) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ValidatorConsumerPubKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ConsumerKey != nil { - { - size, err := m.ConsumerKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.ProviderAddr != nil { - { - size, err := m.ProviderAddr.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintProvider(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ValidatorByConsumerAddr) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ValidatorByConsumerAddr) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ValidatorByConsumerAddr) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ProviderAddr != nil { - { - size, err := m.ProviderAddr.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.ConsumerAddr != nil { - { - size, err := m.ConsumerAddr.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintProvider(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ConsumerAddrsToPrune) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ConsumerAddrsToPrune) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ConsumerAddrsToPrune) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ConsumerAddrsToPrune) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2460,6 +2332,10 @@ func (m *ConsumerAdditionProposal) Size() (n int) { if m.HistoricalEntries != 0 { n += 1 + sovProvider(uint64(m.HistoricalEntries)) } + l = len(m.DistributionTransmissionChannel) + if l > 0 { + n += 1 + l + sovProvider(uint64(l)) + } return n } @@ -2524,8 +2400,8 @@ func (m *GlobalSlashEntry) Size() (n int) { if m.IbcSeqNum != 0 { n += 1 + sovProvider(uint64(m.IbcSeqNum)) } - if m.ProviderValConsAddr != nil { - l = m.ProviderValConsAddr.Size() + l = len(m.ProviderValConsAddr) + if l > 0 { n += 1 + l + sovProvider(uint64(l)) } return n @@ -2560,6 +2436,8 @@ func (m *Params) Size() (n int) { if m.MaxThrottledPackets != 0 { n += 1 + sovProvider(uint64(m.MaxThrottledPackets)) } + l = m.ConsumerRewardDenomRegistrationFee.Size() + n += 1 + l + sovProvider(uint64(l)) return n } @@ -2625,6 +2503,21 @@ func (m *ConsumerRemovalProposals) Size() (n int) { return n } +func (m *AddressList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Addresses) > 0 { + for _, b := range m.Addresses { + l = len(b) + n += 1 + l + sovProvider(uint64(l)) + } + } + return n +} + func (m *ChannelToChain) Size() (n int) { if m == nil { return 0 @@ -2709,55 +2602,14 @@ func (m *VscSendTimestamp) Size() (n int) { return n } -func (m *ConsumerConsAddress) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Address) - if l > 0 { - n += 1 + l + sovProvider(uint64(l)) - } - return n -} - -func (m *ProviderConsAddress) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Address) - if l > 0 { - n += 1 + l + sovProvider(uint64(l)) - } - return n -} - -func (m *ConsumerAddressList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Addresses) > 0 { - for _, e := range m.Addresses { - l = e.Size() - n += 1 + l + sovProvider(uint64(l)) - } - } - return n -} - func (m *KeyAssignmentReplacement) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.ProviderAddr != nil { - l = m.ProviderAddr.Size() + l = len(m.ProviderAddr) + if l > 0 { n += 1 + l + sovProvider(uint64(l)) } if m.PrevCKey != nil { @@ -2780,8 +2632,8 @@ func (m *ValidatorConsumerPubKey) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } - if m.ProviderAddr != nil { - l = m.ProviderAddr.Size() + l = len(m.ProviderAddr) + if l > 0 { n += 1 + l + sovProvider(uint64(l)) } if m.ConsumerKey != nil { @@ -2801,12 +2653,12 @@ func (m *ValidatorByConsumerAddr) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } - if m.ConsumerAddr != nil { - l = m.ConsumerAddr.Size() + l = len(m.ConsumerAddr) + if l > 0 { n += 1 + l + sovProvider(uint64(l)) } - if m.ProviderAddr != nil { - l = m.ProviderAddr.Size() + l = len(m.ProviderAddr) + if l > 0 { n += 1 + l + sovProvider(uint64(l)) } return n @@ -3266,6 +3118,38 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { break } } + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) @@ -3731,7 +3615,7 @@ func (m *GlobalSlashEntry) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderValConsAddr", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -3741,26 +3625,24 @@ func (m *GlobalSlashEntry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } + m.ProviderValConsAddr = append(m.ProviderValConsAddr[:0], dAtA[iNdEx:postIndex]...) if m.ProviderValConsAddr == nil { - m.ProviderValConsAddr = &ProviderConsAddress{} - } - if err := m.ProviderValConsAddr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ProviderValConsAddr = []byte{} } iNdEx = postIndex default: @@ -4064,17 +3946,50 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } - default: - iNdEx = preIndex - skippy, err := skipProvider(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthProvider - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerRewardDenomRegistrationFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ConsumerRewardDenomRegistrationFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProvider(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProvider + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } iNdEx += skippy } @@ -4449,6 +4364,88 @@ func (m *ConsumerRemovalProposals) Unmarshal(dAtA []byte) error { } return nil } +func (m *AddressList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddressList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddressList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addresses = append(m.Addresses, make([]byte, postIndex-iNdEx)) + copy(m.Addresses[len(m.Addresses)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProvider(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProvider + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ChannelToChain) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5012,258 +5009,6 @@ func (m *VscSendTimestamp) Unmarshal(dAtA []byte) error { } return nil } -func (m *ConsumerConsAddress) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ConsumerConsAddress: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsumerConsAddress: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthProvider - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthProvider - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) - if m.Address == nil { - m.Address = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipProvider(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthProvider - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ProviderConsAddress) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ProviderConsAddress: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ProviderConsAddress: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthProvider - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthProvider - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) - if m.Address == nil { - m.Address = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipProvider(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthProvider - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConsumerAddressList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ConsumerAddressList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsumerAddressList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthProvider - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthProvider - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Addresses = append(m.Addresses, &ConsumerConsAddress{}) - if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipProvider(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthProvider - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *KeyAssignmentReplacement) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5297,7 +5042,7 @@ func (m *KeyAssignmentReplacement) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -5307,26 +5052,24 @@ func (m *KeyAssignmentReplacement) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } + m.ProviderAddr = append(m.ProviderAddr[:0], dAtA[iNdEx:postIndex]...) if m.ProviderAddr == nil { - m.ProviderAddr = &ProviderConsAddress{} - } - if err := m.ProviderAddr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ProviderAddr = []byte{} } iNdEx = postIndex case 2: @@ -5470,7 +5213,7 @@ func (m *ValidatorConsumerPubKey) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -5480,26 +5223,24 @@ func (m *ValidatorConsumerPubKey) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } + m.ProviderAddr = append(m.ProviderAddr[:0], dAtA[iNdEx:postIndex]...) if m.ProviderAddr == nil { - m.ProviderAddr = &ProviderConsAddress{} - } - if err := m.ProviderAddr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ProviderAddr = []byte{} } iNdEx = postIndex case 3: @@ -5624,7 +5365,7 @@ func (m *ValidatorByConsumerAddr) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsumerAddr", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -5634,33 +5375,31 @@ func (m *ValidatorByConsumerAddr) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } + m.ConsumerAddr = append(m.ConsumerAddr[:0], dAtA[iNdEx:postIndex]...) if m.ConsumerAddr == nil { - m.ConsumerAddr = &ConsumerConsAddress{} - } - if err := m.ConsumerAddr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ConsumerAddr = []byte{} } iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -5670,26 +5409,24 @@ func (m *ValidatorByConsumerAddr) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } + m.ProviderAddr = append(m.ProviderAddr[:0], dAtA[iNdEx:postIndex]...) if m.ProviderAddr == nil { - m.ProviderAddr = &ProviderConsAddress{} - } - if err := m.ProviderAddr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ProviderAddr = []byte{} } iNdEx = postIndex default: @@ -5823,7 +5560,7 @@ func (m *ConsumerAddrsToPrune) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.ConsumerAddrs == nil { - m.ConsumerAddrs = &ConsumerAddressList{} + m.ConsumerAddrs = &AddressList{} } if err := m.ConsumerAddrs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index d9571acea0..5d4fc19077 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -10,8 +10,8 @@ import ( grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - types "github.com/cosmos/interchain-security/x/ccv/consumer/types" - types1 "github.com/cosmos/interchain-security/x/ccv/types" + types "github.com/cosmos/interchain-security/v2/x/ccv/consumer/types" + types1 "github.com/cosmos/interchain-security/v2/x/ccv/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -632,10 +632,11 @@ var xxx_messageInfo_QueryThrottleStateRequest proto.InternalMessageInfo type QueryThrottleStateResponse struct { // current slash_meter state SlashMeter int64 `protobuf:"varint,1,opt,name=slash_meter,json=slashMeter,proto3" json:"slash_meter,omitempty"` - // allowance of voting power units (int) that the slash meter is given per replenish period - // this also serves as the max value for the meter. + // allowance of voting power units (int) that the slash meter is given per + // replenish period this also serves as the max value for the meter. SlashMeterAllowance int64 `protobuf:"varint,2,opt,name=slash_meter_allowance,json=slashMeterAllowance,proto3" json:"slash_meter_allowance,omitempty"` - // next time the slash meter could potentially be replenished, iff it's not full + // next time the slash meter could potentially be replenished, iff it's not + // full NextReplenishCandidate time.Time `protobuf:"bytes,3,opt,name=next_replenish_candidate,json=nextReplenishCandidate,proto3,stdtime" json:"next_replenish_candidate"` // data relevant to currently throttled slash packets Packets []*ThrottledSlashPacket `protobuf:"bytes,4,rep,name=packets,proto3" json:"packets,omitempty"` @@ -810,7 +811,8 @@ func (m *QueryThrottledConsumerPacketDataResponse) GetPacketDataInstances() []Th return nil } -// A query wrapper type for the global entry and data relevant to a throttled slash packet. +// A query wrapper type for the global entry and data relevant to a throttled +// slash packet. type ThrottledSlashPacket struct { GlobalEntry GlobalSlashEntry `protobuf:"bytes,1,opt,name=global_entry,json=globalEntry,proto3" json:"global_entry"` Data types1.SlashPacketData `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` @@ -863,7 +865,8 @@ func (m *ThrottledSlashPacket) GetData() types1.SlashPacketData { return types1.SlashPacketData{} } -// ThrottledPacketDataWrapper contains either SlashPacketData or VSCMaturedPacketData +// ThrottledPacketDataWrapper contains either SlashPacketData or +// VSCMaturedPacketData type ThrottledPacketDataWrapper struct { // Types that are valid to be assigned to Data: // *ThrottledPacketDataWrapper_SlashPacket @@ -949,6 +952,94 @@ func (*ThrottledPacketDataWrapper) XXX_OneofWrappers() []interface{} { } } +type QueryRegisteredConsumerRewardDenomsRequest struct { +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) Reset() { + *m = QueryRegisteredConsumerRewardDenomsRequest{} +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) String() string { + return proto.CompactTextString(m) +} +func (*QueryRegisteredConsumerRewardDenomsRequest) ProtoMessage() {} +func (*QueryRegisteredConsumerRewardDenomsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{19} +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Merge(m, src) +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest proto.InternalMessageInfo + +type QueryRegisteredConsumerRewardDenomsResponse struct { + Denoms []string `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms,omitempty"` +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) Reset() { + *m = QueryRegisteredConsumerRewardDenomsResponse{} +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) String() string { + return proto.CompactTextString(m) +} +func (*QueryRegisteredConsumerRewardDenomsResponse) ProtoMessage() {} +func (*QueryRegisteredConsumerRewardDenomsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{20} +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.Merge(m, src) +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse proto.InternalMessageInfo + +func (m *QueryRegisteredConsumerRewardDenomsResponse) GetDenoms() []string { + if m != nil { + return m.Denoms + } + return nil +} + func init() { proto.RegisterType((*QueryConsumerGenesisRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisRequest") proto.RegisterType((*QueryConsumerGenesisResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisResponse") @@ -969,6 +1060,8 @@ func init() { proto.RegisterType((*QueryThrottledConsumerPacketDataResponse)(nil), "interchain_security.ccv.provider.v1.QueryThrottledConsumerPacketDataResponse") proto.RegisterType((*ThrottledSlashPacket)(nil), "interchain_security.ccv.provider.v1.ThrottledSlashPacket") proto.RegisterType((*ThrottledPacketDataWrapper)(nil), "interchain_security.ccv.provider.v1.ThrottledPacketDataWrapper") + proto.RegisterType((*QueryRegisteredConsumerRewardDenomsRequest)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsRequest") + proto.RegisterType((*QueryRegisteredConsumerRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsResponse") } func init() { @@ -976,85 +1069,90 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 1236 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcd, 0x6f, 0x1b, 0x45, - 0x1c, 0xf5, 0x26, 0x69, 0x9b, 0x4e, 0x0a, 0x89, 0x26, 0x01, 0xdc, 0x4d, 0x64, 0x87, 0x05, 0x41, - 0x0a, 0x62, 0xb7, 0x76, 0x85, 0xd4, 0x04, 0x52, 0xc7, 0x4e, 0x43, 0x1a, 0xd1, 0x88, 0xb0, 0x89, - 0x8a, 0x04, 0xa8, 0x66, 0xb2, 0x3b, 0x38, 0x2b, 0xd6, 0x3b, 0xdb, 0x9d, 0xf1, 0xb6, 0xe1, 0xe3, - 0xc0, 0x87, 0xa0, 0xc7, 0x4a, 0xfc, 0x03, 0x3d, 0xf1, 0x5f, 0x70, 0xef, 0x8d, 0x8a, 0x5e, 0x7a, - 0x2a, 0x28, 0xe1, 0xc0, 0x11, 0x71, 0x47, 0x42, 0x3b, 0x3b, 0xe3, 0x8f, 0x78, 0x6d, 0xaf, 0xdd, - 0xde, 0x9c, 0x99, 0xf9, 0xbd, 0xdf, 0x7b, 0x2f, 0xbf, 0x19, 0x3f, 0x03, 0xc3, 0xf1, 0x18, 0x0e, - 0xac, 0x03, 0xe4, 0x78, 0x55, 0x8a, 0xad, 0x46, 0xe0, 0xb0, 0x43, 0xc3, 0xb2, 0x42, 0xc3, 0x0f, - 0x48, 0xe8, 0xd8, 0x38, 0x30, 0xc2, 0x82, 0x71, 0xab, 0x81, 0x83, 0x43, 0xdd, 0x0f, 0x08, 0x23, - 0xf0, 0x95, 0x84, 0x02, 0xdd, 0xb2, 0x42, 0x5d, 0x16, 0xe8, 0x61, 0x41, 0x5d, 0xa8, 0x11, 0x52, - 0x73, 0xb1, 0x81, 0x7c, 0xc7, 0x40, 0x9e, 0x47, 0x18, 0x62, 0x0e, 0xf1, 0x68, 0x0c, 0xa1, 0xce, - 0xd5, 0x48, 0x8d, 0xf0, 0x8f, 0x46, 0xf4, 0x49, 0xac, 0xe6, 0x45, 0x0d, 0xff, 0x6b, 0xbf, 0xf1, - 0xb9, 0xc1, 0x9c, 0x3a, 0xa6, 0x0c, 0xd5, 0x7d, 0x71, 0xe0, 0xd5, 0x5e, 0x54, 0xc3, 0x82, 0x21, - 0x08, 0x30, 0xa2, 0x16, 0x7a, 0x9d, 0xb2, 0x88, 0x47, 0x1b, 0xf5, 0x58, 0x50, 0x0d, 0x7b, 0x98, - 0x3a, 0x92, 0x4f, 0x31, 0x8d, 0x07, 0x4d, 0x79, 0xbc, 0x46, 0xbb, 0x0c, 0xe6, 0x3f, 0x8c, 0x5c, - 0x59, 0x17, 0xa8, 0x9b, 0x31, 0xa2, 0x89, 0x6f, 0x35, 0x30, 0x65, 0xf0, 0x3c, 0x98, 0x8c, 0xf1, - 0x1c, 0x3b, 0xab, 0x2c, 0x2a, 0x4b, 0x67, 0xcd, 0x33, 0xfc, 0xef, 0x2d, 0x5b, 0xfb, 0x1a, 0x2c, - 0x24, 0x57, 0x52, 0x9f, 0x78, 0x14, 0xc3, 0x4f, 0xc1, 0x73, 0x82, 0x5e, 0x95, 0x32, 0xc4, 0x30, - 0xaf, 0x9f, 0x2a, 0x16, 0xf4, 0x5e, 0xc6, 0x4b, 0x61, 0x7a, 0x58, 0xd0, 0x05, 0xd8, 0x6e, 0x54, - 0x58, 0x99, 0x78, 0xf0, 0x24, 0x9f, 0x31, 0xcf, 0xd5, 0xda, 0xd6, 0xb4, 0x05, 0xa0, 0x76, 0x74, - 0x5f, 0x8f, 0xf0, 0x24, 0x6d, 0x0d, 0x9d, 0x50, 0x25, 0x77, 0x05, 0xb5, 0x0a, 0x38, 0xcd, 0xfb, - 0xd3, 0xac, 0xb2, 0x38, 0xbe, 0x34, 0x55, 0x7c, 0x43, 0x4f, 0x31, 0x0c, 0x3a, 0x07, 0x31, 0x45, - 0xa5, 0x76, 0x01, 0xbc, 0xde, 0xdd, 0x62, 0x97, 0xa1, 0x80, 0xed, 0x04, 0xc4, 0x27, 0x14, 0xb9, - 0x4d, 0x36, 0x77, 0x15, 0xb0, 0x34, 0xf8, 0x6c, 0xd3, 0xb6, 0xb3, 0xbe, 0x5c, 0x14, 0x96, 0x5d, - 0x49, 0x47, 0x4f, 0x80, 0x97, 0x6d, 0xdb, 0x89, 0xa6, 0xb4, 0x05, 0xdd, 0x02, 0xd4, 0x96, 0xc0, - 0x6b, 0x49, 0x4c, 0x88, 0xdf, 0x45, 0xfa, 0x47, 0x25, 0x59, 0x60, 0xc7, 0x51, 0xc1, 0xf9, 0x93, - 0x6e, 0xce, 0xab, 0x43, 0x71, 0x36, 0x71, 0x9d, 0x84, 0xc8, 0x4d, 0xa4, 0x5c, 0x02, 0xa7, 0x78, - 0xeb, 0x3e, 0xb3, 0x08, 0xe7, 0xc1, 0x59, 0xcb, 0x75, 0xb0, 0xc7, 0xa2, 0xbd, 0x31, 0xbe, 0x37, - 0x19, 0x2f, 0x6c, 0xd9, 0xda, 0x4f, 0x0a, 0x78, 0x99, 0x2b, 0xb9, 0x81, 0x5c, 0xc7, 0x46, 0x8c, - 0x04, 0x6d, 0x56, 0x05, 0x83, 0x27, 0x1d, 0xae, 0x82, 0x19, 0x49, 0xba, 0x8a, 0x6c, 0x3b, 0xc0, - 0x94, 0xc6, 0x4d, 0x2a, 0xf0, 0xdf, 0x27, 0xf9, 0xe7, 0x0f, 0x51, 0xdd, 0x5d, 0xd1, 0xc4, 0x86, - 0x66, 0x4e, 0xcb, 0xb3, 0xe5, 0x78, 0x65, 0x65, 0xf2, 0xee, 0xfd, 0x7c, 0xe6, 0xef, 0xfb, 0xf9, - 0x8c, 0xf6, 0x01, 0xd0, 0xfa, 0x11, 0x11, 0x6e, 0x5e, 0x00, 0x33, 0xf2, 0x2a, 0x34, 0xdb, 0xc5, - 0x8c, 0xa6, 0xad, 0xb6, 0xf3, 0x51, 0xb3, 0x6e, 0x69, 0x3b, 0x6d, 0xcd, 0xd3, 0x49, 0xeb, 0xea, - 0xd5, 0x47, 0xda, 0x89, 0xfe, 0xfd, 0xa4, 0x75, 0x12, 0x69, 0x49, 0xeb, 0x72, 0x52, 0x48, 0x3b, - 0xe1, 0x9a, 0x36, 0x0f, 0xce, 0x73, 0xc0, 0xbd, 0x83, 0x80, 0x30, 0xe6, 0x62, 0x7e, 0xed, 0xe5, - 0x70, 0xfe, 0x32, 0x26, 0xae, 0xff, 0x89, 0x5d, 0xd1, 0x26, 0x0f, 0xa6, 0xa8, 0x8b, 0xe8, 0x41, - 0xb5, 0x8e, 0x19, 0x0e, 0x78, 0x87, 0x71, 0x13, 0xf0, 0xa5, 0xed, 0x68, 0x05, 0x16, 0xc1, 0x0b, - 0x6d, 0x07, 0xaa, 0xc8, 0x75, 0xc9, 0x6d, 0xe4, 0x59, 0x98, 0x6b, 0x1f, 0x37, 0x67, 0x5b, 0x47, - 0xcb, 0x72, 0x0b, 0xde, 0x04, 0x59, 0x0f, 0xdf, 0x61, 0xd5, 0x00, 0xfb, 0x2e, 0xf6, 0x1c, 0x7a, - 0x50, 0xb5, 0x90, 0x67, 0x47, 0x62, 0x71, 0x76, 0x9c, 0xcf, 0xbc, 0xaa, 0xc7, 0x4f, 0xbf, 0x2e, - 0x9f, 0x7e, 0x7d, 0x4f, 0x3e, 0xfd, 0x95, 0xc9, 0xe8, 0x0d, 0xbb, 0xf7, 0x47, 0x5e, 0x31, 0x5f, - 0x8c, 0x50, 0x4c, 0x09, 0xb2, 0x2e, 0x31, 0xe0, 0x2e, 0x38, 0xe3, 0x23, 0xeb, 0x0b, 0xcc, 0x68, - 0x76, 0x82, 0xbf, 0x4a, 0xcb, 0xa9, 0xae, 0x90, 0x74, 0xc0, 0xde, 0x8d, 0x38, 0xef, 0x70, 0x04, - 0x53, 0x22, 0x69, 0x57, 0xc5, 0x25, 0x6e, 0x9e, 0x92, 0x13, 0x17, 0x1f, 0xbc, 0x8a, 0x18, 0x4a, - 0xf1, 0xd4, 0xff, 0x2e, 0x1f, 0xb0, 0xbe, 0x30, 0xc2, 0xfc, 0x3e, 0xd3, 0x06, 0xc1, 0x04, 0x75, - 0xbe, 0x8c, 0x5d, 0x9e, 0x30, 0xf9, 0x67, 0x78, 0x1b, 0xcc, 0xfa, 0x4d, 0x90, 0x2d, 0x8f, 0xb2, - 0xc8, 0x6c, 0x9a, 0x1d, 0xe7, 0x16, 0x94, 0x86, 0xb3, 0xa0, 0xc5, 0xe6, 0xa3, 0x00, 0xf9, 0x3e, - 0x0e, 0xc4, 0x57, 0x47, 0x52, 0x07, 0xed, 0x57, 0x05, 0xcc, 0x25, 0x99, 0x07, 0x6f, 0x82, 0x73, - 0x35, 0x97, 0xec, 0x23, 0xb7, 0x8a, 0x3d, 0x16, 0x1c, 0x8a, 0x07, 0xed, 0xed, 0x54, 0x54, 0x36, - 0x79, 0x21, 0x47, 0xdb, 0x88, 0x8a, 0x05, 0x81, 0xa9, 0x18, 0x90, 0x2f, 0xc1, 0x0d, 0x30, 0x61, - 0x23, 0x86, 0xb8, 0x0b, 0x53, 0xc5, 0x37, 0x7b, 0xe2, 0x86, 0x05, 0xbd, 0x8d, 0x56, 0x44, 0x5e, - 0xa0, 0xf1, 0x72, 0xed, 0xb1, 0x02, 0xd4, 0xde, 0xca, 0xe1, 0x0e, 0x38, 0x17, 0x8f, 0x78, 0xac, - 0x5d, 0xa8, 0x18, 0xa6, 0xdb, 0xb5, 0x8c, 0x19, 0x5f, 0x23, 0xe1, 0xcb, 0x67, 0x00, 0x86, 0xd4, - 0xaa, 0xd6, 0x11, 0x6b, 0x04, 0xd8, 0x96, 0xb8, 0xb1, 0x8a, 0x8b, 0xfd, 0x70, 0x6f, 0xec, 0xae, - 0x6f, 0xc7, 0x45, 0x1d, 0xe0, 0x33, 0x21, 0xb5, 0x3a, 0xd6, 0x2b, 0xa7, 0x63, 0x67, 0x8a, 0x3f, - 0x4c, 0x83, 0x53, 0x7c, 0xde, 0xe0, 0x91, 0x02, 0xe6, 0x92, 0x52, 0x06, 0x5c, 0x4b, 0xf5, 0xef, - 0xe8, 0x13, 0x6d, 0xd4, 0xf2, 0x53, 0x20, 0xc4, 0xa3, 0xae, 0x6d, 0x7c, 0xf7, 0xe8, 0xaf, 0x9f, - 0xc7, 0x4a, 0x70, 0x75, 0x70, 0xfa, 0x6c, 0xbe, 0xb2, 0x22, 0xc5, 0x18, 0x5f, 0xc9, 0x4b, 0xf2, - 0x0d, 0x7c, 0xa4, 0x80, 0xd9, 0x84, 0xb8, 0x02, 0x4b, 0xc3, 0x33, 0xec, 0x88, 0x41, 0xea, 0xda, - 0xe8, 0x00, 0x42, 0xe1, 0x32, 0x57, 0x78, 0x09, 0x16, 0x86, 0x50, 0x18, 0x07, 0x24, 0xf8, 0xed, - 0x18, 0xc8, 0xf6, 0x48, 0x3d, 0x14, 0x5e, 0x1f, 0x91, 0x59, 0x62, 0xc0, 0x52, 0xb7, 0x9f, 0x11, - 0x9a, 0x10, 0x7d, 0x8d, 0x8b, 0xae, 0xc0, 0xb5, 0x61, 0x45, 0x47, 0x41, 0x37, 0x60, 0xd5, 0x66, - 0x76, 0x81, 0xff, 0x29, 0xe0, 0xa5, 0xe4, 0x10, 0x45, 0xe1, 0xfb, 0x23, 0x93, 0xee, 0x4e, 0x6b, - 0xea, 0xf5, 0x67, 0x03, 0x26, 0x0c, 0xd8, 0xe4, 0x06, 0x94, 0x61, 0x69, 0x04, 0x03, 0x88, 0xdf, - 0xa6, 0xff, 0x1f, 0x45, 0x7c, 0x4f, 0x27, 0x26, 0x1e, 0xf8, 0x5e, 0x7a, 0xd6, 0xfd, 0xb2, 0x9b, - 0xba, 0xf9, 0xd4, 0x38, 0x42, 0x78, 0x99, 0x0b, 0x7f, 0x07, 0x2e, 0xa7, 0xf8, 0x39, 0x29, 0x81, - 0xaa, 0x1d, 0x01, 0x2a, 0x41, 0x72, 0x7b, 0x12, 0x1a, 0x49, 0x72, 0x42, 0xa6, 0x1b, 0x49, 0x72, - 0x52, 0x24, 0x1b, 0x4d, 0x72, 0x47, 0x88, 0x83, 0xbf, 0x29, 0x00, 0x76, 0xa7, 0x31, 0x78, 0x25, - 0x3d, 0xc5, 0xa4, 0x90, 0xa7, 0x96, 0x46, 0xae, 0x17, 0xd2, 0x2e, 0x73, 0x69, 0x45, 0x78, 0x71, - 0xb0, 0x34, 0x26, 0x00, 0xe2, 0x9f, 0xaa, 0xf0, 0xfb, 0x31, 0xb0, 0x38, 0x28, 0xf0, 0x0c, 0xf3, - 0x86, 0x0d, 0x8e, 0x5f, 0xc3, 0xbc, 0x61, 0x29, 0x52, 0x98, 0x56, 0xe1, 0xda, 0xdf, 0x85, 0x2b, - 0x83, 0xb5, 0xfb, 0xd8, 0xb3, 0x1d, 0xaf, 0xd6, 0x9a, 0x63, 0x11, 0x1e, 0x2b, 0x7b, 0x0f, 0x8e, - 0x72, 0xca, 0xc3, 0xa3, 0x9c, 0xf2, 0xe7, 0x51, 0x4e, 0xb9, 0x77, 0x9c, 0xcb, 0x3c, 0x3c, 0xce, - 0x65, 0x1e, 0x1f, 0xe7, 0x32, 0x1f, 0xaf, 0xd4, 0x1c, 0x76, 0xd0, 0xd8, 0xd7, 0x2d, 0x52, 0x37, - 0x2c, 0x42, 0xeb, 0x84, 0xb6, 0xb5, 0x79, 0xab, 0xd9, 0xe6, 0xce, 0x09, 0x93, 0x0f, 0x7d, 0x4c, - 0xf7, 0x4f, 0xf3, 0x74, 0x7c, 0xe9, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0xf5, 0x7d, 0x58, - 0xb2, 0x11, 0x00, 0x00, + // 1322 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0xdc, 0x44, + 0x18, 0x5d, 0x6f, 0xd2, 0x34, 0x99, 0x14, 0x5a, 0xa6, 0xa5, 0x6c, 0xdd, 0x6a, 0xb7, 0xb8, 0x08, + 0xd2, 0x16, 0xec, 0xee, 0x56, 0x48, 0x4d, 0x20, 0xdd, 0xec, 0x26, 0x21, 0x8d, 0xda, 0xa8, 0xc1, + 0xa9, 0x5a, 0x09, 0x50, 0xcd, 0xc4, 0x1e, 0x36, 0x16, 0x5e, 0x8f, 0xeb, 0x99, 0x75, 0x1a, 0x7e, + 0x1c, 0x00, 0x09, 0x7a, 0xac, 0x84, 0xb8, 0x71, 0xe8, 0x89, 0xff, 0x82, 0x7b, 0x6f, 0x54, 0xf4, + 0xd2, 0x53, 0x41, 0x09, 0x07, 0x8e, 0x88, 0x3b, 0x12, 0xf2, 0x78, 0xbc, 0x3f, 0xb2, 0xde, 0x5d, + 0xef, 0x36, 0xb7, 0xdd, 0xf1, 0x7c, 0xef, 0x7b, 0xef, 0xe9, 0x9b, 0xf1, 0x33, 0xd0, 0x6c, 0x97, + 0x61, 0xdf, 0xdc, 0x42, 0xb6, 0x6b, 0x50, 0x6c, 0x36, 0x7c, 0x9b, 0xed, 0x68, 0xa6, 0x19, 0x68, + 0x9e, 0x4f, 0x02, 0xdb, 0xc2, 0xbe, 0x16, 0x14, 0xb5, 0x7b, 0x0d, 0xec, 0xef, 0xa8, 0x9e, 0x4f, + 0x18, 0x81, 0xe7, 0x12, 0x0a, 0x54, 0xd3, 0x0c, 0xd4, 0xb8, 0x40, 0x0d, 0x8a, 0xf2, 0x99, 0x1a, + 0x21, 0x35, 0x07, 0x6b, 0xc8, 0xb3, 0x35, 0xe4, 0xba, 0x84, 0x21, 0x66, 0x13, 0x97, 0x46, 0x10, + 0xf2, 0x89, 0x1a, 0xa9, 0x11, 0xfe, 0x53, 0x0b, 0x7f, 0x89, 0xd5, 0x82, 0xa8, 0xe1, 0xff, 0x36, + 0x1b, 0x9f, 0x69, 0xcc, 0xae, 0x63, 0xca, 0x50, 0xdd, 0x13, 0x1b, 0xde, 0xe8, 0x45, 0x35, 0x28, + 0x6a, 0x82, 0x00, 0x23, 0x72, 0xb1, 0xd7, 0x2e, 0x93, 0xb8, 0xb4, 0x51, 0x8f, 0x04, 0xd5, 0xb0, + 0x8b, 0xa9, 0x1d, 0xf3, 0x29, 0xa5, 0xf1, 0xa0, 0x29, 0x8f, 0xd7, 0x28, 0x57, 0xc0, 0xe9, 0x0f, + 0x43, 0x57, 0x16, 0x05, 0xea, 0x4a, 0x84, 0xa8, 0xe3, 0x7b, 0x0d, 0x4c, 0x19, 0x3c, 0x05, 0x26, + 0x23, 0x3c, 0xdb, 0xca, 0x49, 0x67, 0xa5, 0x99, 0x29, 0xfd, 0x30, 0xff, 0xbf, 0x6a, 0x29, 0x5f, + 0x81, 0x33, 0xc9, 0x95, 0xd4, 0x23, 0x2e, 0xc5, 0xf0, 0x13, 0xf0, 0x92, 0xa0, 0x67, 0x50, 0x86, + 0x18, 0xe6, 0xf5, 0xd3, 0xa5, 0xa2, 0xda, 0xcb, 0xf8, 0x58, 0x98, 0x1a, 0x14, 0x55, 0x01, 0xb6, + 0x11, 0x16, 0x56, 0xc7, 0x1f, 0x3f, 0x2f, 0x64, 0xf4, 0x23, 0xb5, 0xb6, 0x35, 0xe5, 0x0c, 0x90, + 0x3b, 0xba, 0x2f, 0x86, 0x78, 0x31, 0x6d, 0x05, 0xed, 0x53, 0x15, 0x3f, 0x15, 0xd4, 0xaa, 0x60, + 0x82, 0xf7, 0xa7, 0x39, 0xe9, 0xec, 0xd8, 0xcc, 0x74, 0xe9, 0x82, 0x9a, 0x62, 0x18, 0x54, 0x0e, + 0xa2, 0x8b, 0x4a, 0xe5, 0x3c, 0x78, 0xab, 0xbb, 0xc5, 0x06, 0x43, 0x3e, 0x5b, 0xf7, 0x89, 0x47, + 0x28, 0x72, 0x9a, 0x6c, 0x1e, 0x48, 0x60, 0x66, 0xf0, 0xde, 0xa6, 0x6d, 0x53, 0x5e, 0xbc, 0x28, + 0x2c, 0xbb, 0x9a, 0x8e, 0x9e, 0x00, 0xaf, 0x58, 0x96, 0x1d, 0x4e, 0x69, 0x0b, 0xba, 0x05, 0xa8, + 0xcc, 0x80, 0x37, 0x93, 0x98, 0x10, 0xaf, 0x8b, 0xf4, 0xf7, 0x52, 0xb2, 0xc0, 0x8e, 0xad, 0x82, + 0xf3, 0xc7, 0xdd, 0x9c, 0xe7, 0x87, 0xe2, 0xac, 0xe3, 0x3a, 0x09, 0x90, 0x93, 0x48, 0xb9, 0x0c, + 0x0e, 0xf1, 0xd6, 0x7d, 0x66, 0x11, 0x9e, 0x06, 0x53, 0xa6, 0x63, 0x63, 0x97, 0x85, 0xcf, 0xb2, + 0xfc, 0xd9, 0x64, 0xb4, 0xb0, 0x6a, 0x29, 0x3f, 0x48, 0xe0, 0x75, 0xae, 0xe4, 0x36, 0x72, 0x6c, + 0x0b, 0x31, 0xe2, 0xb7, 0x59, 0xe5, 0x0f, 0x9e, 0x74, 0x38, 0x0f, 0x8e, 0xc5, 0xa4, 0x0d, 0x64, + 0x59, 0x3e, 0xa6, 0x34, 0x6a, 0x52, 0x85, 0xff, 0x3e, 0x2f, 0xbc, 0xbc, 0x83, 0xea, 0xce, 0x9c, + 0x22, 0x1e, 0x28, 0xfa, 0xd1, 0x78, 0x6f, 0x25, 0x5a, 0x99, 0x9b, 0x7c, 0xf0, 0xa8, 0x90, 0xf9, + 0xfb, 0x51, 0x21, 0xa3, 0xdc, 0x04, 0x4a, 0x3f, 0x22, 0xc2, 0xcd, 0xf3, 0xe0, 0x58, 0x7c, 0x14, + 0x9a, 0xed, 0x22, 0x46, 0x47, 0xcd, 0xb6, 0xfd, 0x61, 0xb3, 0x6e, 0x69, 0xeb, 0x6d, 0xcd, 0xd3, + 0x49, 0xeb, 0xea, 0xd5, 0x47, 0xda, 0xbe, 0xfe, 0xfd, 0xa4, 0x75, 0x12, 0x69, 0x49, 0xeb, 0x72, + 0x52, 0x48, 0xdb, 0xe7, 0x9a, 0x72, 0x1a, 0x9c, 0xe2, 0x80, 0xb7, 0xb6, 0x7c, 0xc2, 0x98, 0x83, + 0xf9, 0xb1, 0x8f, 0x87, 0xf3, 0x97, 0xac, 0x38, 0xfe, 0xfb, 0x9e, 0x8a, 0x36, 0x05, 0x30, 0x4d, + 0x1d, 0x44, 0xb7, 0x8c, 0x3a, 0x66, 0xd8, 0xe7, 0x1d, 0xc6, 0x74, 0xc0, 0x97, 0xd6, 0xc2, 0x15, + 0x58, 0x02, 0xaf, 0xb6, 0x6d, 0x30, 0x90, 0xe3, 0x90, 0x6d, 0xe4, 0x9a, 0x98, 0x6b, 0x1f, 0xd3, + 0x8f, 0xb7, 0xb6, 0x56, 0xe2, 0x47, 0xf0, 0x2e, 0xc8, 0xb9, 0xf8, 0x3e, 0x33, 0x7c, 0xec, 0x39, + 0xd8, 0xb5, 0xe9, 0x96, 0x61, 0x22, 0xd7, 0x0a, 0xc5, 0xe2, 0xdc, 0x18, 0x9f, 0x79, 0x59, 0x8d, + 0xae, 0x7e, 0x35, 0xbe, 0xfa, 0xd5, 0x5b, 0xf1, 0xd5, 0x5f, 0x9d, 0x0c, 0xef, 0xb0, 0x87, 0x7f, + 0x14, 0x24, 0xfd, 0x64, 0x88, 0xa2, 0xc7, 0x20, 0x8b, 0x31, 0x06, 0xdc, 0x00, 0x87, 0x3d, 0x64, + 0x7e, 0x8e, 0x19, 0xcd, 0x8d, 0xf3, 0x5b, 0x69, 0x36, 0xd5, 0x11, 0x8a, 0x1d, 0xb0, 0x36, 0x42, + 0xce, 0xeb, 0x1c, 0x41, 0x8f, 0x91, 0x94, 0x25, 0x71, 0x88, 0x9b, 0xbb, 0xe2, 0x89, 0x8b, 0x36, + 0x2e, 0x21, 0x86, 0x52, 0x5c, 0xf5, 0xbf, 0xc7, 0x17, 0x58, 0x5f, 0x18, 0x61, 0x7e, 0x9f, 0x69, + 0x83, 0x60, 0x9c, 0xda, 0x5f, 0x44, 0x2e, 0x8f, 0xeb, 0xfc, 0x37, 0xdc, 0x06, 0xc7, 0xbd, 0x26, + 0xc8, 0xaa, 0x4b, 0x59, 0x68, 0x36, 0xcd, 0x8d, 0x71, 0x0b, 0xca, 0xc3, 0x59, 0xd0, 0x62, 0x73, + 0xc7, 0x47, 0x9e, 0x87, 0x7d, 0xf1, 0xea, 0x48, 0xea, 0xa0, 0xfc, 0x2a, 0x81, 0x13, 0x49, 0xe6, + 0xc1, 0xbb, 0xe0, 0x48, 0xcd, 0x21, 0x9b, 0xc8, 0x31, 0xb0, 0xcb, 0xfc, 0x1d, 0x71, 0xa1, 0xbd, + 0x9b, 0x8a, 0xca, 0x0a, 0x2f, 0xe4, 0x68, 0xcb, 0x61, 0xb1, 0x20, 0x30, 0x1d, 0x01, 0xf2, 0x25, + 0xb8, 0x0c, 0xc6, 0x2d, 0xc4, 0x10, 0x77, 0x61, 0xba, 0x74, 0xb1, 0x27, 0x6e, 0x50, 0x54, 0xdb, + 0x68, 0x85, 0xe4, 0x05, 0x1a, 0x2f, 0x57, 0x9e, 0x49, 0x40, 0xee, 0xad, 0x1c, 0xae, 0x83, 0x23, + 0xd1, 0x88, 0x47, 0xda, 0x85, 0x8a, 0x61, 0xba, 0x5d, 0xcb, 0xe8, 0xd1, 0x31, 0x12, 0xbe, 0x7c, + 0x0a, 0x60, 0x40, 0x4d, 0xa3, 0x8e, 0x58, 0xc3, 0xc7, 0x56, 0x8c, 0x1b, 0xa9, 0xb8, 0xd4, 0x0f, + 0xf7, 0xf6, 0xc6, 0xe2, 0x5a, 0x54, 0xd4, 0x01, 0x7e, 0x2c, 0xa0, 0x66, 0xc7, 0x7a, 0x75, 0x22, + 0x72, 0x46, 0x79, 0x1b, 0x5c, 0xe0, 0xe3, 0xa6, 0xe3, 0x9a, 0x4d, 0x19, 0xf6, 0x5b, 0xf3, 0xa6, + 0xe3, 0x6d, 0xe4, 0x5b, 0x4b, 0xd8, 0x25, 0xf5, 0xe6, 0x9b, 0x6a, 0x19, 0x5c, 0x4c, 0xb5, 0x5b, + 0xcc, 0xe7, 0x49, 0x30, 0x61, 0xf1, 0x15, 0xfe, 0xf2, 0x9f, 0xd2, 0xc5, 0xbf, 0xd2, 0xcf, 0xaf, + 0x80, 0x43, 0x1c, 0x07, 0xee, 0x4a, 0xe0, 0x44, 0x52, 0xb4, 0x81, 0x0b, 0xa9, 0x66, 0xa0, 0x4f, + 0x9e, 0x92, 0x2b, 0x2f, 0x80, 0x10, 0xf1, 0x57, 0x96, 0xbf, 0x7d, 0xfa, 0xd7, 0x8f, 0xd9, 0x32, + 0x9c, 0x1f, 0x1c, 0x79, 0x9b, 0x57, 0xbb, 0x88, 0x4e, 0xda, 0x97, 0xf1, 0xc9, 0xfc, 0x1a, 0x3e, + 0x95, 0xc0, 0xf1, 0x84, 0x8c, 0x04, 0xcb, 0xc3, 0x33, 0xec, 0xc8, 0x5e, 0xf2, 0xc2, 0xe8, 0x00, + 0x42, 0xe1, 0x2c, 0x57, 0x78, 0x19, 0x16, 0x87, 0x50, 0x18, 0xa5, 0x32, 0xf8, 0x4d, 0x16, 0xe4, + 0x7a, 0x44, 0x2d, 0x0a, 0x6f, 0x8c, 0xc8, 0x2c, 0x31, 0xd5, 0xc9, 0x6b, 0x07, 0x84, 0x26, 0x44, + 0x5f, 0xe3, 0xa2, 0xab, 0x70, 0x61, 0x58, 0xd1, 0x61, 0xba, 0xf6, 0x99, 0xd1, 0x0c, 0x4c, 0xf0, + 0x3f, 0x09, 0xbc, 0x96, 0x9c, 0xdc, 0x28, 0xbc, 0x3e, 0x32, 0xe9, 0xee, 0x88, 0x28, 0xdf, 0x38, + 0x18, 0x30, 0x61, 0xc0, 0x0a, 0x37, 0xa0, 0x02, 0xcb, 0x23, 0x18, 0x40, 0xbc, 0x36, 0xfd, 0xff, + 0x48, 0x22, 0x1c, 0x24, 0xc6, 0x2c, 0xf8, 0x41, 0x7a, 0xd6, 0xfd, 0x02, 0xa3, 0xbc, 0xf2, 0xc2, + 0x38, 0x42, 0x78, 0x85, 0x0b, 0x7f, 0x0f, 0xce, 0xa6, 0xf8, 0x86, 0x8d, 0x81, 0x8c, 0x8e, 0xd4, + 0x96, 0x20, 0xb9, 0x3d, 0x7e, 0x8d, 0x24, 0x39, 0x21, 0x48, 0x8e, 0x24, 0x39, 0x29, 0x07, 0x8e, + 0x26, 0xb9, 0x23, 0x39, 0xc2, 0xdf, 0x24, 0x00, 0xbb, 0x23, 0x20, 0xbc, 0x9a, 0x9e, 0x62, 0x52, + 0xb2, 0x94, 0xcb, 0x23, 0xd7, 0x0b, 0x69, 0x57, 0xb8, 0xb4, 0x12, 0xbc, 0x34, 0x58, 0x1a, 0x13, + 0x00, 0xd1, 0xf7, 0x31, 0xfc, 0x2e, 0x0b, 0xce, 0x0e, 0x4a, 0x59, 0xc3, 0xdc, 0x61, 0x83, 0x33, + 0xdf, 0x30, 0x77, 0x58, 0x8a, 0xe8, 0xa7, 0x54, 0xb9, 0xf6, 0xf7, 0xe1, 0xdc, 0x60, 0xed, 0x1e, + 0x76, 0x2d, 0xdb, 0xad, 0xb5, 0xe6, 0x58, 0x24, 0x56, 0xf8, 0x53, 0x16, 0x9c, 0x4b, 0xf1, 0x3a, + 0x87, 0x37, 0xd3, 0x53, 0x4f, 0x15, 0x23, 0xe4, 0xf5, 0x83, 0x03, 0x14, 0x76, 0x5c, 0xe7, 0x76, + 0x2c, 0xc3, 0xc5, 0xc1, 0x76, 0xf8, 0x4d, 0xc4, 0x96, 0x23, 0x3e, 0xc7, 0x34, 0xa2, 0x78, 0x52, + 0xbd, 0xf3, 0x78, 0x37, 0x2f, 0x3d, 0xd9, 0xcd, 0x4b, 0x7f, 0xee, 0xe6, 0xa5, 0x87, 0x7b, 0xf9, + 0xcc, 0x93, 0xbd, 0x7c, 0xe6, 0xd9, 0x5e, 0x3e, 0xf3, 0xd1, 0x7c, 0xcd, 0x66, 0x5b, 0x8d, 0x4d, + 0xd5, 0x24, 0x75, 0xcd, 0x24, 0xb4, 0x4e, 0x68, 0x5b, 0xbf, 0x77, 0x9a, 0xfd, 0x82, 0x92, 0x76, + 0x7f, 0xdf, 0xfc, 0xed, 0x78, 0x98, 0x6e, 0x4e, 0xf0, 0xaf, 0x95, 0xcb, 0xff, 0x07, 0x00, 0x00, + 0xff, 0xff, 0xb7, 0x37, 0x44, 0xeb, 0x42, 0x13, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1085,11 +1183,15 @@ type QueryClient interface { // QueryProviderAddr returns the provider chain validator // given a consumer chain validator address QueryValidatorProviderAddr(ctx context.Context, in *QueryValidatorProviderAddrRequest, opts ...grpc.CallOption) (*QueryValidatorProviderAddrResponse, error) - // QueryThrottleState returns the main on-chain state relevant to currently throttled slash packets + // QueryThrottleState returns the main on-chain state relevant to currently + // throttled slash packets QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) - // QueryThrottledConsumerPacketData returns a list of pending packet data instances - // (slash packet and vsc matured) for a single consumer chain + // QueryThrottledConsumerPacketData returns a list of pending packet data + // instances (slash packet and vsc matured) for a single consumer chain QueryThrottledConsumerPacketData(ctx context.Context, in *QueryThrottledConsumerPacketDataRequest, opts ...grpc.CallOption) (*QueryThrottledConsumerPacketDataResponse, error) + // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward + // denoms that are registered + QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) } type queryClient struct { @@ -1172,6 +1274,15 @@ func (c *queryClient) QueryThrottledConsumerPacketData(ctx context.Context, in * return out, nil } +func (c *queryClient) QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) { + out := new(QueryRegisteredConsumerRewardDenomsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ConsumerGenesis queries the genesis state needed to start a consumer chain @@ -1190,11 +1301,15 @@ type QueryServer interface { // QueryProviderAddr returns the provider chain validator // given a consumer chain validator address QueryValidatorProviderAddr(context.Context, *QueryValidatorProviderAddrRequest) (*QueryValidatorProviderAddrResponse, error) - // QueryThrottleState returns the main on-chain state relevant to currently throttled slash packets + // QueryThrottleState returns the main on-chain state relevant to currently + // throttled slash packets QueryThrottleState(context.Context, *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) - // QueryThrottledConsumerPacketData returns a list of pending packet data instances - // (slash packet and vsc matured) for a single consumer chain + // QueryThrottledConsumerPacketData returns a list of pending packet data + // instances (slash packet and vsc matured) for a single consumer chain QueryThrottledConsumerPacketData(context.Context, *QueryThrottledConsumerPacketDataRequest) (*QueryThrottledConsumerPacketDataResponse, error) + // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward + // denoms that are registered + QueryRegisteredConsumerRewardDenoms(context.Context, *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1225,6 +1340,9 @@ func (*UnimplementedQueryServer) QueryThrottleState(ctx context.Context, req *Qu func (*UnimplementedQueryServer) QueryThrottledConsumerPacketData(ctx context.Context, req *QueryThrottledConsumerPacketDataRequest) (*QueryThrottledConsumerPacketDataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryThrottledConsumerPacketData not implemented") } +func (*UnimplementedQueryServer) QueryRegisteredConsumerRewardDenoms(ctx context.Context, req *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryRegisteredConsumerRewardDenoms not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1374,6 +1492,24 @@ func _Query_QueryThrottledConsumerPacketData_Handler(srv interface{}, ctx contex return interceptor(ctx, in, info, handler) } +func _Query_QueryRegisteredConsumerRewardDenoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRegisteredConsumerRewardDenomsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, req.(*QueryRegisteredConsumerRewardDenomsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Query", HandlerType: (*QueryServer)(nil), @@ -1410,6 +1546,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryThrottledConsumerPacketData", Handler: _Query_QueryThrottledConsumerPacketData_Handler, }, + { + MethodName: "QueryRegisteredConsumerRewardDenoms", + Handler: _Query_QueryRegisteredConsumerRewardDenoms_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/query.proto", @@ -2099,6 +2239,61 @@ func (m *ThrottledPacketDataWrapper_VscMaturedPacket) MarshalToSizedBuffer(dAtA } return len(dAtA) - i, nil } +func (m *QueryRegisteredConsumerRewardDenomsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denoms) > 0 { + for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denoms[iNdEx]) + copy(dAtA[i:], m.Denoms[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denoms[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2395,6 +2590,29 @@ func (m *ThrottledPacketDataWrapper_VscMaturedPacket) Size() (n int) { } return n } +func (m *QueryRegisteredConsumerRewardDenomsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Denoms) > 0 { + for _, s := range m.Denoms { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 @@ -4137,6 +4355,138 @@ func (m *ThrottledPacketDataWrapper) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ccv/provider/types/query.pb.gw.go b/x/ccv/provider/types/query.pb.gw.go index cb5e2f2411..6a249ca2a2 100644 --- a/x/ccv/provider/types/query.pb.gw.go +++ b/x/ccv/provider/types/query.pb.gw.go @@ -267,6 +267,24 @@ func local_request_Query_QueryThrottledConsumerPacketData_0(ctx context.Context, } +func request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredConsumerRewardDenomsRequest + var metadata runtime.ServerMetadata + + msg, err := client.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredConsumerRewardDenomsRequest + var metadata runtime.ServerMetadata + + msg, err := server.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -457,6 +475,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryRegisteredConsumerRewardDenoms_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -658,6 +699,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryRegisteredConsumerRewardDenoms_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -677,6 +738,8 @@ var ( pattern_Query_QueryThrottleState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "throttle_state"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_QueryThrottledConsumerPacketData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "pending_consumer_packets"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryRegisteredConsumerRewardDenoms_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "registered_consumer_reward_denoms"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -695,4 +758,6 @@ var ( forward_Query_QueryThrottleState_0 = runtime.ForwardResponseMessage forward_Query_QueryThrottledConsumerPacketData_0 = runtime.ForwardResponseMessage + + forward_Query_QueryRegisteredConsumerRewardDenoms_0 = runtime.ForwardResponseMessage ) diff --git a/x/ccv/provider/types/throttle.go b/x/ccv/provider/types/throttle.go index 70a3bb49e2..e41396eb3a 100644 --- a/x/ccv/provider/types/throttle.go +++ b/x/ccv/provider/types/throttle.go @@ -12,6 +12,6 @@ func NewGlobalSlashEntry(recvTime time.Time, consumerChainID string, RecvTime: recvTime.UTC(), // UTC prevents serialization inconsistencies ConsumerChainID: consumerChainID, IbcSeqNum: ibcSeqNum, - ProviderValConsAddr: &providerValConsAddr, + ProviderValConsAddr: providerValConsAddr.ToSdkConsAddr(), } } diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index b2bfd35c37..746f92b417 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -111,9 +111,92 @@ func (m *MsgAssignConsumerKeyResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAssignConsumerKeyResponse proto.InternalMessageInfo +// MsgRegisterConsumerRewardDenom allows an account to register +// a consumer reward denom, i.e., add it to the list of denoms +// accepted by the provider as rewards. +type MsgRegisterConsumerRewardDenom struct { + Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` + Depositor string `protobuf:"bytes,2,opt,name=depositor,proto3" json:"depositor,omitempty"` +} + +func (m *MsgRegisterConsumerRewardDenom) Reset() { *m = MsgRegisterConsumerRewardDenom{} } +func (m *MsgRegisterConsumerRewardDenom) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterConsumerRewardDenom) ProtoMessage() {} +func (*MsgRegisterConsumerRewardDenom) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{2} +} +func (m *MsgRegisterConsumerRewardDenom) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterConsumerRewardDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterConsumerRewardDenom.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRegisterConsumerRewardDenom) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterConsumerRewardDenom.Merge(m, src) +} +func (m *MsgRegisterConsumerRewardDenom) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterConsumerRewardDenom) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterConsumerRewardDenom.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterConsumerRewardDenom proto.InternalMessageInfo + +// MsgRegisterConsumerRewardDenomResponse defines the +// Msg/RegisterConsumerRewardDenom response type. +type MsgRegisterConsumerRewardDenomResponse struct { +} + +func (m *MsgRegisterConsumerRewardDenomResponse) Reset() { + *m = MsgRegisterConsumerRewardDenomResponse{} +} +func (m *MsgRegisterConsumerRewardDenomResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterConsumerRewardDenomResponse) ProtoMessage() {} +func (*MsgRegisterConsumerRewardDenomResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{3} +} +func (m *MsgRegisterConsumerRewardDenomResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterConsumerRewardDenomResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterConsumerRewardDenomResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRegisterConsumerRewardDenomResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterConsumerRewardDenomResponse.Merge(m, src) +} +func (m *MsgRegisterConsumerRewardDenomResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterConsumerRewardDenomResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterConsumerRewardDenomResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterConsumerRewardDenomResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgAssignConsumerKey)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKey") proto.RegisterType((*MsgAssignConsumerKeyResponse)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKeyResponse") + proto.RegisterType((*MsgRegisterConsumerRewardDenom)(nil), "interchain_security.ccv.provider.v1.MsgRegisterConsumerRewardDenom") + proto.RegisterType((*MsgRegisterConsumerRewardDenomResponse)(nil), "interchain_security.ccv.provider.v1.MsgRegisterConsumerRewardDenomResponse") } func init() { @@ -121,31 +204,36 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 369 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0x3d, 0x4f, 0xeb, 0x30, - 0x14, 0x8d, 0x5f, 0xa5, 0xf7, 0xfa, 0x4c, 0x41, 0x22, 0xea, 0xd0, 0x56, 0x55, 0x0a, 0x61, 0x61, - 0x80, 0x58, 0x85, 0x01, 0xd1, 0xad, 0x65, 0x42, 0xa8, 0x4b, 0xc5, 0xc4, 0x12, 0xa5, 0x8e, 0x71, - 0x2d, 0x1a, 0x3b, 0xb2, 0x9d, 0xa8, 0xf9, 0x07, 0x8c, 0x30, 0x21, 0xb6, 0xfe, 0x1c, 0xc6, 0x8e, - 0x4c, 0x08, 0xb5, 0x0b, 0x33, 0xbf, 0x00, 0x35, 0x1f, 0x54, 0x88, 0x0e, 0x88, 0xed, 0xde, 0x7b, - 0x8e, 0xcf, 0x39, 0xf2, 0xbd, 0xf0, 0x80, 0x71, 0x4d, 0x24, 0x1e, 0x79, 0x8c, 0xbb, 0x8a, 0xe0, - 0x48, 0x32, 0x9d, 0x20, 0x8c, 0x63, 0x14, 0x4a, 0x11, 0x33, 0x9f, 0x48, 0x14, 0xb7, 0x91, 0x9e, - 0x38, 0xa1, 0x14, 0x5a, 0x98, 0x7b, 0x6b, 0xd8, 0x0e, 0xc6, 0xb1, 0x53, 0xb0, 0x9d, 0xb8, 0xdd, - 0x68, 0x52, 0x21, 0xe8, 0x98, 0x20, 0x2f, 0x64, 0xc8, 0xe3, 0x5c, 0x68, 0x4f, 0x33, 0xc1, 0x55, - 0x26, 0xd1, 0xa8, 0x52, 0x41, 0x45, 0x5a, 0xa2, 0x65, 0x95, 0x4f, 0xeb, 0x58, 0xa8, 0x40, 0x28, - 0x37, 0x03, 0xb2, 0xa6, 0x80, 0x72, 0xb9, 0xb4, 0x1b, 0x46, 0xd7, 0xc8, 0xe3, 0x49, 0x06, 0xd9, - 0x0f, 0x00, 0x56, 0xfb, 0x8a, 0x76, 0x95, 0x62, 0x94, 0x9f, 0x09, 0xae, 0xa2, 0x80, 0xc8, 0x0b, - 0x92, 0x98, 0x75, 0x58, 0xce, 0x42, 0x32, 0xbf, 0x06, 0x76, 0xc0, 0xfe, 0xff, 0xc1, 0xbf, 0xb4, - 0x3f, 0xf7, 0xcd, 0x13, 0xb8, 0x59, 0x84, 0x75, 0x3d, 0xdf, 0x97, 0xb5, 0x3f, 0x4b, 0xbc, 0x67, - 0xbe, 0xbf, 0xb4, 0xb6, 0x12, 0x2f, 0x18, 0x77, 0xec, 0xe5, 0x94, 0x28, 0x65, 0x0f, 0x2a, 0x05, - 0xb1, 0xeb, 0xfb, 0xd2, 0xdc, 0x85, 0x15, 0x9c, 0x5b, 0xb8, 0x37, 0x24, 0xa9, 0x95, 0x52, 0xdd, - 0x0d, 0xbc, 0xb2, 0xed, 0x94, 0x6f, 0xa7, 0x2d, 0xe3, 0x6d, 0xda, 0x32, 0x6c, 0x0b, 0x36, 0xd7, - 0x05, 0x1b, 0x10, 0x15, 0x0a, 0xae, 0xc8, 0xd1, 0x23, 0x80, 0xa5, 0xbe, 0xa2, 0xe6, 0x3d, 0x80, - 0xdb, 0xdf, 0xe3, 0x9f, 0x3a, 0x3f, 0xf8, 0x67, 0x67, 0x9d, 0x41, 0xa3, 0xfb, 0xeb, 0xa7, 0x45, - 0xb6, 0xde, 0xe5, 0xd3, 0xdc, 0x02, 0xb3, 0xb9, 0x05, 0x5e, 0xe7, 0x16, 0xb8, 0x5b, 0x58, 0xc6, - 0x6c, 0x61, 0x19, 0xcf, 0x0b, 0xcb, 0xb8, 0xea, 0x50, 0xa6, 0x47, 0xd1, 0xd0, 0xc1, 0x22, 0xc8, - 0x77, 0x84, 0x56, 0x6e, 0x87, 0x9f, 0xe7, 0x33, 0xf9, 0x7a, 0x40, 0x3a, 0x09, 0x89, 0x1a, 0xfe, - 0x4d, 0x57, 0x76, 0xfc, 0x11, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x60, 0x67, 0xb6, 0x71, 0x02, 0x00, - 0x00, + // 453 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x3d, 0x6b, 0x14, 0x41, + 0x18, 0xc7, 0x77, 0x13, 0xd4, 0x64, 0x8c, 0x82, 0xc3, 0x15, 0x97, 0xf3, 0xd8, 0xd3, 0x15, 0x24, + 0x85, 0xee, 0x90, 0x58, 0x88, 0x01, 0x8b, 0x4b, 0x6c, 0x24, 0x5c, 0xb3, 0x8d, 0x60, 0xe1, 0xb1, + 0x37, 0x33, 0x4e, 0x06, 0xb3, 0xf3, 0x2c, 0xf3, 0xcc, 0xad, 0xd9, 0x6f, 0x60, 0xa9, 0x95, 0x6d, + 0xbe, 0x81, 0x5f, 0x43, 0xb0, 0x49, 0x69, 0x25, 0x72, 0xd7, 0x58, 0xfb, 0x09, 0x64, 0xdf, 0x3c, + 0xc5, 0xe3, 0x08, 0x92, 0xee, 0x79, 0xdb, 0xff, 0xff, 0xb7, 0x33, 0xf3, 0x90, 0x07, 0xda, 0x38, + 0x69, 0xf9, 0x71, 0xa2, 0xcd, 0x18, 0x25, 0x9f, 0x5a, 0xed, 0x0a, 0xc6, 0x79, 0xce, 0x32, 0x0b, + 0xb9, 0x16, 0xd2, 0xb2, 0x7c, 0x97, 0xb9, 0xd3, 0x28, 0xb3, 0xe0, 0x80, 0xde, 0x5b, 0x32, 0x1d, + 0x71, 0x9e, 0x47, 0xed, 0x74, 0x94, 0xef, 0xf6, 0xfa, 0x0a, 0x40, 0x9d, 0x48, 0x96, 0x64, 0x9a, + 0x25, 0xc6, 0x80, 0x4b, 0x9c, 0x06, 0x83, 0xb5, 0x44, 0xaf, 0xa3, 0x40, 0x41, 0x15, 0xb2, 0x32, + 0x6a, 0xaa, 0xdb, 0x1c, 0x30, 0x05, 0x1c, 0xd7, 0x8d, 0x3a, 0x69, 0x5b, 0x8d, 0x5c, 0x95, 0x4d, + 0xa6, 0xaf, 0x59, 0x62, 0x8a, 0xba, 0x15, 0x7e, 0xf4, 0x49, 0x67, 0x84, 0x6a, 0x88, 0xa8, 0x95, + 0x39, 0x04, 0x83, 0xd3, 0x54, 0xda, 0x23, 0x59, 0xd0, 0x6d, 0xb2, 0x51, 0x43, 0x6a, 0xd1, 0xf5, + 0xef, 0xf8, 0x3b, 0x9b, 0xf1, 0xb5, 0x2a, 0x7f, 0x2e, 0xe8, 0x63, 0x72, 0xa3, 0x85, 0x1d, 0x27, + 0x42, 0xd8, 0xee, 0x5a, 0xd9, 0x3f, 0xa0, 0x3f, 0xbf, 0x0d, 0x6e, 0x16, 0x49, 0x7a, 0xb2, 0x1f, + 0x96, 0x55, 0x89, 0x18, 0xc6, 0x5b, 0xed, 0xe0, 0x50, 0x08, 0x4b, 0xef, 0x92, 0x2d, 0xde, 0x58, + 0x8c, 0xdf, 0xc8, 0xa2, 0xbb, 0x5e, 0xe9, 0x5e, 0xe7, 0x0b, 0xdb, 0xfd, 0x8d, 0x77, 0x67, 0x03, + 0xef, 0xc7, 0xd9, 0xc0, 0x0b, 0x03, 0xd2, 0x5f, 0x06, 0x16, 0x4b, 0xcc, 0xc0, 0xa0, 0x0c, 0x5f, + 0x91, 0x60, 0x84, 0x2a, 0x96, 0x4a, 0xa3, 0x93, 0xb6, 0x9d, 0x88, 0xe5, 0xdb, 0xc4, 0x8a, 0x67, + 0xd2, 0x40, 0x4a, 0x3b, 0xe4, 0x8a, 0x28, 0x83, 0x86, 0xbf, 0x4e, 0x68, 0x9f, 0x6c, 0x0a, 0x99, + 0x01, 0x6a, 0x07, 0x0d, 0x79, 0xbc, 0x28, 0xfc, 0xe1, 0xbf, 0x43, 0xee, 0xaf, 0xd6, 0x6f, 0x49, + 0xf6, 0xbe, 0xac, 0x91, 0xf5, 0x11, 0x2a, 0xfa, 0xc1, 0x27, 0xb7, 0xfe, 0x3d, 0xc8, 0x27, 0xd1, + 0x05, 0x6e, 0x3c, 0x5a, 0xf6, 0xab, 0xbd, 0xe1, 0x7f, 0x7f, 0xda, 0xb2, 0xd1, 0x4f, 0x3e, 0xb9, + 0xbd, 0xea, 0x8c, 0x0e, 0x2f, 0x6a, 0xb1, 0x42, 0xa4, 0x77, 0x74, 0x09, 0x22, 0x2d, 0xf1, 0xc1, + 0x8b, 0xcf, 0xb3, 0xc0, 0x3f, 0x9f, 0x05, 0xfe, 0xf7, 0x59, 0xe0, 0xbf, 0x9f, 0x07, 0xde, 0xf9, + 0x3c, 0xf0, 0xbe, 0xce, 0x03, 0xef, 0xe5, 0x53, 0xa5, 0xdd, 0xf1, 0x74, 0x12, 0x71, 0x48, 0x9b, + 0xf7, 0xcd, 0x16, 0xbe, 0x0f, 0x7f, 0xaf, 0x5e, 0xbe, 0xc7, 0x4e, 0xff, 0xde, 0x3f, 0x57, 0x64, + 0x12, 0x27, 0x57, 0xab, 0x17, 0xff, 0xe8, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x53, 0xb5, + 0xb8, 0xb0, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -161,6 +249,7 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { AssignConsumerKey(ctx context.Context, in *MsgAssignConsumerKey, opts ...grpc.CallOption) (*MsgAssignConsumerKeyResponse, error) + RegisterConsumerRewardDenom(ctx context.Context, in *MsgRegisterConsumerRewardDenom, opts ...grpc.CallOption) (*MsgRegisterConsumerRewardDenomResponse, error) } type msgClient struct { @@ -180,9 +269,19 @@ func (c *msgClient) AssignConsumerKey(ctx context.Context, in *MsgAssignConsumer return out, nil } +func (c *msgClient) RegisterConsumerRewardDenom(ctx context.Context, in *MsgRegisterConsumerRewardDenom, opts ...grpc.CallOption) (*MsgRegisterConsumerRewardDenomResponse, error) { + out := new(MsgRegisterConsumerRewardDenomResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/RegisterConsumerRewardDenom", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AssignConsumerKey(context.Context, *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) + RegisterConsumerRewardDenom(context.Context, *MsgRegisterConsumerRewardDenom) (*MsgRegisterConsumerRewardDenomResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -192,6 +291,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) AssignConsumerKey(ctx context.Context, req *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AssignConsumerKey not implemented") } +func (*UnimplementedMsgServer) RegisterConsumerRewardDenom(ctx context.Context, req *MsgRegisterConsumerRewardDenom) (*MsgRegisterConsumerRewardDenomResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterConsumerRewardDenom not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -215,6 +317,24 @@ func _Msg_AssignConsumerKey_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Msg_RegisterConsumerRewardDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRegisterConsumerRewardDenom) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterConsumerRewardDenom(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/RegisterConsumerRewardDenom", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterConsumerRewardDenom(ctx, req.(*MsgRegisterConsumerRewardDenom)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -223,6 +343,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "AssignConsumerKey", Handler: _Msg_AssignConsumerKey_Handler, }, + { + MethodName: "RegisterConsumerRewardDenom", + Handler: _Msg_RegisterConsumerRewardDenom_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/tx.proto", @@ -295,6 +419,66 @@ func (m *MsgAssignConsumerKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *MsgRegisterConsumerRewardDenom) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgRegisterConsumerRewardDenom) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterConsumerRewardDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Depositor) > 0 { + i -= len(m.Depositor) + copy(dAtA[i:], m.Depositor) + i = encodeVarintTx(dAtA, i, uint64(len(m.Depositor))) + i-- + dAtA[i] = 0x12 + } + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRegisterConsumerRewardDenomResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgRegisterConsumerRewardDenomResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterConsumerRewardDenomResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -336,6 +520,32 @@ func (m *MsgAssignConsumerKeyResponse) Size() (n int) { return n } +func (m *MsgRegisterConsumerRewardDenom) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Depositor) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgRegisterConsumerRewardDenomResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -538,6 +748,170 @@ func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgRegisterConsumerRewardDenom) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRegisterConsumerRewardDenom: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterConsumerRewardDenom: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Depositor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Depositor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRegisterConsumerRewardDenomResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRegisterConsumerRewardDenomResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterConsumerRewardDenomResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ccv/types/ccv.go b/x/ccv/types/ccv.go index b41a7c6993..62111a7b65 100644 --- a/x/ccv/types/ccv.go +++ b/x/ccv/types/ccv.go @@ -3,7 +3,7 @@ package types import ( "fmt" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -19,10 +19,10 @@ func NewValidatorSetChangePacketData(valUpdates []abci.ValidatorUpdate, valUpdat // ValidateBasic is used for validating the CCV packet data. func (vsc ValidatorSetChangePacketData) ValidateBasic() error { if len(vsc.ValidatorUpdates) == 0 { - return sdkerrors.Wrap(ErrInvalidPacketData, "validator updates cannot be empty") + return errorsmod.Wrap(ErrInvalidPacketData, "validator updates cannot be empty") } if vsc.ValsetUpdateId == 0 { - return sdkerrors.Wrap(ErrInvalidPacketData, "valset update id cannot be equal to zero") + return errorsmod.Wrap(ErrInvalidPacketData, "valset update id cannot be equal to zero") } return nil } @@ -41,7 +41,7 @@ func NewVSCMaturedPacketData(valUpdateID uint64) *VSCMaturedPacketData { // ValidateBasic is used for validating the VSCMatured packet data. func (mat VSCMaturedPacketData) ValidateBasic() error { if mat.ValsetUpdateId == 0 { - return sdkerrors.Wrap(ErrInvalidPacketData, "vscId cannot be equal to zero") + return errorsmod.Wrap(ErrInvalidPacketData, "vscId cannot be equal to zero") } return nil } @@ -61,11 +61,11 @@ func NewSlashPacketData(validator abci.Validator, valUpdateId uint64, infraction func (vdt SlashPacketData) ValidateBasic() error { if len(vdt.Validator.Address) == 0 || vdt.Validator.Power == 0 { - return sdkerrors.Wrap(ErrInvalidPacketData, "validator fields cannot be empty") + return errorsmod.Wrap(ErrInvalidPacketData, "validator fields cannot be empty") } if vdt.Infraction == stakingtypes.Infraction_INFRACTION_UNSPECIFIED { - return sdkerrors.Wrap(ErrInvalidPacketData, "invalid infraction type") + return errorsmod.Wrap(ErrInvalidPacketData, "invalid infraction type") } return nil diff --git a/x/ccv/types/ccv.pb.go b/x/ccv/types/ccv.pb.go index f20ccea0f0..ea2d38dc84 100644 --- a/x/ccv/types/ccv.pb.go +++ b/x/ccv/types/ccv.pb.go @@ -281,7 +281,8 @@ func (m *SlashPacketData) GetInfraction() types1.Infraction { return types1.Infraction_INFRACTION_UNSPECIFIED } -// MaturedUnbondingOps defines a list of ids corresponding to ids of matured unbonding operations. +// MaturedUnbondingOps defines a list of ids corresponding to ids of matured +// unbonding operations. type MaturedUnbondingOps struct { Ids []uint64 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` } @@ -481,51 +482,51 @@ func init() { } var fileDescriptor_68bd5f3242e6f29c = []byte{ - // 693 bytes of a gzipped FileDescriptorProto + // 697 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xcf, 0x6a, 0xdb, 0x4a, 0x14, 0xc6, 0xa5, 0x58, 0x04, 0x32, 0x86, 0x44, 0xd1, 0xf5, 0xbd, 0x38, 0xba, 0xad, 0x22, 0x44, - 0xa0, 0xa6, 0xa5, 0x52, 0xad, 0x6c, 0x4a, 0xbb, 0x69, 0xec, 0x38, 0xd8, 0xe4, 0x9f, 0x91, 0xe2, - 0x94, 0x76, 0x23, 0xc6, 0xd2, 0xc4, 0x1e, 0x6c, 0x6b, 0x8c, 0x66, 0x2c, 0xea, 0x37, 0x28, 0x59, - 0xf5, 0x05, 0xb2, 0x2a, 0x7d, 0x90, 0xee, 0xb2, 0x0c, 0x74, 0x93, 0x55, 0x28, 0xc9, 0x1b, 0xf4, - 0x09, 0x8a, 0x64, 0xd9, 0x71, 0x6c, 0xc5, 0x90, 0x95, 0xc7, 0x67, 0xce, 0xf9, 0xc4, 0xf7, 0x9b, - 0x8f, 0x03, 0xb6, 0xb0, 0xcf, 0x50, 0xe0, 0xb6, 0x21, 0xf6, 0x1d, 0x8a, 0xdc, 0x41, 0x80, 0xd9, - 0xd0, 0x70, 0xdd, 0xd0, 0x08, 0x8b, 0xd1, 0x8f, 0xde, 0x0f, 0x08, 0x23, 0x92, 0x9c, 0xd2, 0xa5, - 0x47, 0xd7, 0x61, 0x51, 0xde, 0x72, 0x09, 0xed, 0x11, 0x6a, 0x50, 0x06, 0x3b, 0xd8, 0x6f, 0x19, - 0x61, 0xb1, 0x89, 0x18, 0x2c, 0x8e, 0xff, 0x8f, 0x14, 0xe4, 0x5c, 0x8b, 0xb4, 0x48, 0x7c, 0x34, - 0xa2, 0x53, 0x52, 0xfd, 0x9f, 0x21, 0xdf, 0x43, 0x41, 0x0f, 0xfb, 0xcc, 0x80, 0x4d, 0x17, 0x1b, - 0x6c, 0xd8, 0x47, 0x74, 0x74, 0xa9, 0x5d, 0xf3, 0xe0, 0xd9, 0x29, 0xec, 0x62, 0x0f, 0x32, 0x12, - 0xd8, 0x88, 0x95, 0xdb, 0xd0, 0x6f, 0xa1, 0x3a, 0x74, 0x3b, 0x88, 0xed, 0x42, 0x06, 0x25, 0x02, - 0xd6, 0xc3, 0xf1, 0xbd, 0x33, 0xe8, 0x7b, 0x90, 0x21, 0x9a, 0xe7, 0xd5, 0x4c, 0x21, 0x6b, 0xaa, - 0xfa, 0xbd, 0xb2, 0x1e, 0x29, 0xeb, 0x13, 0xa5, 0x46, 0xdc, 0x58, 0x52, 0x2f, 0x6f, 0x36, 0xb9, - 0x3f, 0x37, 0x9b, 0xf9, 0x21, 0xec, 0x75, 0xdf, 0x69, 0x73, 0x42, 0x9a, 0x25, 0x86, 0x0f, 0x47, - 0xa8, 0x54, 0x00, 0x51, 0x8d, 0x22, 0x96, 0x34, 0x39, 0xd8, 0xcb, 0x2f, 0xa9, 0x7c, 0x41, 0xb0, - 0x56, 0x47, 0xf5, 0x51, 0x63, 0xcd, 0x93, 0x9e, 0x03, 0x40, 0xbb, 0x90, 0xb6, 0x1d, 0xe8, 0x76, - 0x68, 0x3e, 0xa3, 0x66, 0x0a, 0x2b, 0xd6, 0x4a, 0x5c, 0xd9, 0x71, 0x3b, 0x54, 0x23, 0x60, 0xe3, - 0x31, 0x67, 0x54, 0xb2, 0x80, 0xd0, 0xc5, 0x94, 0x25, 0x4e, 0xde, 0xea, 0x8f, 0xb3, 0xd7, 0x17, - 0xe1, 0x29, 0x09, 0x91, 0x43, 0x2b, 0xd6, 0xd2, 0x3e, 0x80, 0xdc, 0xa9, 0x5d, 0x3e, 0x84, 0x6c, - 0x10, 0x20, 0x6f, 0x0a, 0x61, 0x9a, 0x23, 0x3e, 0xcd, 0x91, 0xf6, 0x8b, 0x07, 0x6b, 0x76, 0x64, - 0x60, 0x6a, 0xda, 0x02, 0x2b, 0x13, 0x46, 0xf1, 0x58, 0xd6, 0x94, 0x1f, 0x07, 0x5f, 0xca, 0x27, - 0xc8, 0xc5, 0x19, 0xe4, 0x9a, 0x75, 0x2f, 0xf3, 0x04, 0xc6, 0x25, 0x00, 0xb0, 0x7f, 0x16, 0x40, - 0x97, 0x61, 0xe2, 0xe7, 0x33, 0x2a, 0x5f, 0x58, 0x35, 0x35, 0x7d, 0x94, 0x46, 0x7d, 0x9c, 0xbe, - 0x24, 0x8d, 0x7a, 0x6d, 0xd2, 0x69, 0x4d, 0x4d, 0x69, 0x2f, 0xc0, 0x3f, 0x09, 0x94, 0x86, 0xdf, - 0x24, 0xbe, 0x87, 0xfd, 0xd6, 0x71, 0x9f, 0x4a, 0x22, 0xc8, 0x60, 0x6f, 0x94, 0x25, 0xc1, 0x8a, - 0x8e, 0xda, 0x8f, 0x25, 0x20, 0x95, 0x89, 0x4f, 0x07, 0x3d, 0x14, 0x4c, 0x11, 0xd8, 0x03, 0x42, - 0x14, 0xd9, 0xd8, 0xfc, 0xaa, 0x69, 0x2e, 0x7a, 0xab, 0xf9, 0xe9, 0x93, 0x61, 0x1f, 0x59, 0xf1, - 0xbc, 0xf4, 0x11, 0xac, 0xd1, 0x87, 0x70, 0x63, 0xd3, 0x59, 0xf3, 0xd5, 0x22, 0xc9, 0x99, 0xf7, - 0xa8, 0x72, 0xd6, 0xac, 0x8a, 0x74, 0x06, 0x72, 0x21, 0x75, 0xe7, 0x1e, 0x3e, 0xc6, 0x95, 0x35, - 0xdf, 0x2c, 0x0c, 0x57, 0x4a, 0x60, 0xaa, 0x9c, 0x95, 0xaa, 0x57, 0x5a, 0x06, 0x82, 0x07, 0x19, - 0xd4, 0x9a, 0xe0, 0xbf, 0x79, 0xa3, 0x07, 0x98, 0x32, 0xa9, 0xfa, 0x20, 0xd6, 0xfa, 0xd3, 0x50, - 0x4d, 0x87, 0xf9, 0xe5, 0x4f, 0x3e, 0xed, 0x23, 0x11, 0x4d, 0xe9, 0x3d, 0x50, 0xcb, 0xc7, 0x47, - 0x76, 0xe3, 0xb0, 0x62, 0x39, 0xf5, 0x9d, 0xf2, 0x7e, 0xe5, 0xc4, 0x39, 0xf9, 0x54, 0xaf, 0x38, - 0x8d, 0x23, 0xbb, 0x5e, 0x29, 0xd7, 0xf6, 0x6a, 0x95, 0x5d, 0x91, 0x93, 0xff, 0x3d, 0xbf, 0x50, - 0xd7, 0x1b, 0x3e, 0xed, 0x23, 0x17, 0x9f, 0xe1, 0xb1, 0x0f, 0xc9, 0x00, 0x72, 0xea, 0xb0, 0x7d, - 0xb0, 0x63, 0x57, 0x45, 0x5e, 0x5e, 0x3b, 0xbf, 0x50, 0xb3, 0x53, 0xcc, 0xa5, 0x6d, 0xb0, 0x91, - 0x3a, 0x10, 0x91, 0x13, 0x97, 0xe4, 0xdc, 0xf9, 0x85, 0x2a, 0x9e, 0xce, 0xd0, 0x92, 0x85, 0xaf, - 0xdf, 0x15, 0xae, 0xb4, 0x7f, 0x79, 0xab, 0xf0, 0x57, 0xb7, 0x0a, 0xff, 0xfb, 0x56, 0xe1, 0xbf, - 0xdd, 0x29, 0xdc, 0xd5, 0x9d, 0xc2, 0x5d, 0xdf, 0x29, 0xdc, 0xe7, 0x62, 0x0b, 0xb3, 0xf6, 0xa0, - 0xa9, 0xbb, 0xa4, 0x67, 0x24, 0xab, 0xf5, 0x1e, 0xd5, 0xeb, 0xc9, 0x8e, 0xfe, 0x12, 0x6f, 0xe9, - 0x78, 0x5f, 0x36, 0x97, 0xe3, 0x85, 0xb9, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xee, 0x44, - 0xe0, 0xcd, 0x05, 0x00, 0x00, + 0xa0, 0xa6, 0xa5, 0x52, 0xad, 0x74, 0x51, 0xda, 0x4d, 0x63, 0xc7, 0xc1, 0xa6, 0xf9, 0x63, 0xa4, + 0x38, 0xa5, 0xdd, 0x88, 0xb1, 0x34, 0xb1, 0x07, 0xdb, 0x1a, 0xa3, 0x19, 0x8b, 0xfa, 0x0d, 0x4a, + 0x56, 0x7d, 0x81, 0xac, 0x4a, 0x1f, 0xa4, 0xbb, 0x2c, 0x03, 0xdd, 0x64, 0x15, 0x4a, 0xf2, 0x06, + 0x7d, 0x82, 0x22, 0x59, 0x76, 0x1c, 0x5b, 0x31, 0x64, 0xe5, 0xf1, 0x99, 0x73, 0x3e, 0xf1, 0xfd, + 0xe6, 0xe3, 0x80, 0x2d, 0xec, 0x33, 0x14, 0xb8, 0x6d, 0x88, 0x7d, 0x87, 0x22, 0x77, 0x10, 0x60, + 0x36, 0x34, 0x5c, 0x37, 0x34, 0xc2, 0x62, 0xf4, 0xa3, 0xf7, 0x03, 0xc2, 0x88, 0x24, 0xa7, 0x74, + 0xe9, 0xd1, 0x75, 0x58, 0x94, 0xb7, 0x5c, 0x42, 0x7b, 0x84, 0x1a, 0x94, 0xc1, 0x0e, 0xf6, 0x5b, + 0x46, 0x58, 0x6c, 0x22, 0x06, 0x8b, 0xe3, 0xff, 0x23, 0x05, 0x39, 0xd7, 0x22, 0x2d, 0x12, 0x1f, + 0x8d, 0xe8, 0x94, 0x54, 0xff, 0x67, 0xc8, 0xf7, 0x50, 0xd0, 0xc3, 0x3e, 0x33, 0x60, 0xd3, 0xc5, + 0x06, 0x1b, 0xf6, 0x11, 0x1d, 0x5d, 0x6a, 0x57, 0x3c, 0x78, 0x72, 0x02, 0xbb, 0xd8, 0x83, 0x8c, + 0x04, 0x36, 0x62, 0xe5, 0x36, 0xf4, 0x5b, 0xa8, 0x0e, 0xdd, 0x0e, 0x62, 0xbb, 0x90, 0x41, 0x89, + 0x80, 0xf5, 0x70, 0x7c, 0xef, 0x0c, 0xfa, 0x1e, 0x64, 0x88, 0xe6, 0x79, 0x35, 0x53, 0xc8, 0x9a, + 0xaa, 0x7e, 0xa7, 0xac, 0x47, 0xca, 0xfa, 0x44, 0xa9, 0x11, 0x37, 0x96, 0xd4, 0x8b, 0xeb, 0x4d, + 0xee, 0xcf, 0xf5, 0x66, 0x7e, 0x08, 0x7b, 0xdd, 0xb7, 0xda, 0x9c, 0x90, 0x66, 0x89, 0xe1, 0xfd, + 0x11, 0x2a, 0x15, 0x40, 0x54, 0xa3, 0x88, 0x25, 0x4d, 0x0e, 0xf6, 0xf2, 0x4b, 0x2a, 0x5f, 0x10, + 0xac, 0xd5, 0x51, 0x7d, 0xd4, 0x58, 0xf3, 0xa4, 0xa7, 0x00, 0xd0, 0x2e, 0xa4, 0x6d, 0x07, 0xba, + 0x1d, 0x9a, 0xcf, 0xa8, 0x99, 0xc2, 0x8a, 0xb5, 0x12, 0x57, 0x76, 0xdc, 0x0e, 0xd5, 0x08, 0xd8, + 0x78, 0xc8, 0x19, 0x95, 0x2c, 0x20, 0x74, 0x31, 0x65, 0x89, 0x93, 0x37, 0xfa, 0xc3, 0xec, 0xf5, + 0x45, 0x78, 0x4a, 0x42, 0xe4, 0xd0, 0x8a, 0xb5, 0xb4, 0xf7, 0x20, 0x77, 0x62, 0x97, 0x0f, 0x20, + 0x1b, 0x04, 0xc8, 0x9b, 0x42, 0x98, 0xe6, 0x88, 0x4f, 0x73, 0xa4, 0xfd, 0xe2, 0xc1, 0x9a, 0x1d, + 0x19, 0x98, 0x9a, 0xb6, 0xc0, 0xca, 0x84, 0x51, 0x3c, 0x96, 0x35, 0xe5, 0x87, 0xc1, 0x97, 0xf2, + 0x09, 0x72, 0x71, 0x06, 0xb9, 0x66, 0xdd, 0xc9, 0x3c, 0x82, 0x71, 0x09, 0x00, 0xec, 0x9f, 0x06, + 0xd0, 0x65, 0x98, 0xf8, 0xf9, 0x8c, 0xca, 0x17, 0x56, 0x4d, 0x4d, 0x1f, 0xa5, 0x51, 0x1f, 0xa7, + 0x2f, 0x49, 0xa3, 0x5e, 0x9b, 0x74, 0x5a, 0x53, 0x53, 0xda, 0x33, 0xf0, 0x4f, 0x02, 0xa5, 0xe1, + 0x37, 0x89, 0xef, 0x61, 0xbf, 0x75, 0xd4, 0xa7, 0x92, 0x08, 0x32, 0xd8, 0x1b, 0x65, 0x49, 0xb0, + 0xa2, 0xa3, 0xf6, 0x63, 0x09, 0x48, 0x65, 0xe2, 0xd3, 0x41, 0x0f, 0x05, 0x53, 0x04, 0xf6, 0x80, + 0x10, 0x45, 0x36, 0x36, 0xbf, 0x6a, 0x9a, 0x8b, 0xde, 0x6a, 0x7e, 0xfa, 0x78, 0xd8, 0x47, 0x56, + 0x3c, 0x2f, 0x7d, 0x04, 0x6b, 0xf4, 0x3e, 0xdc, 0xd8, 0x74, 0xd6, 0x7c, 0xb1, 0x48, 0x72, 0xe6, + 0x3d, 0xaa, 0x9c, 0x35, 0xab, 0x22, 0x9d, 0x82, 0x5c, 0x48, 0xdd, 0xb9, 0x87, 0x8f, 0x71, 0x65, + 0xcd, 0x57, 0x0b, 0xc3, 0x95, 0x12, 0x98, 0x2a, 0x67, 0xa5, 0xea, 0x95, 0x96, 0x81, 0xe0, 0x41, + 0x06, 0xb5, 0x26, 0xf8, 0x6f, 0xde, 0xe8, 0x3e, 0xa6, 0x4c, 0xaa, 0xde, 0x8b, 0xb5, 0xfe, 0x38, + 0x54, 0xd3, 0x61, 0x7e, 0xfe, 0x93, 0x4f, 0xfb, 0x48, 0x44, 0x53, 0x7a, 0x07, 0xd4, 0xf2, 0xd1, + 0xa1, 0xdd, 0x38, 0xa8, 0x58, 0x4e, 0x7d, 0xa7, 0xfc, 0xa1, 0x72, 0xec, 0x1c, 0x7f, 0xaa, 0x57, + 0x9c, 0xc6, 0xa1, 0x5d, 0xaf, 0x94, 0x6b, 0x7b, 0xb5, 0xca, 0xae, 0xc8, 0xc9, 0xff, 0x9e, 0x9d, + 0xab, 0xeb, 0x0d, 0x9f, 0xf6, 0x91, 0x8b, 0x4f, 0xf1, 0xd8, 0x87, 0x64, 0x00, 0x39, 0x75, 0xd8, + 0xde, 0xdf, 0xb1, 0xab, 0x22, 0x2f, 0xaf, 0x9d, 0x9d, 0xab, 0xd9, 0x29, 0xe6, 0xd2, 0x36, 0xd8, + 0x48, 0x1d, 0x88, 0xc8, 0x89, 0x4b, 0x72, 0xee, 0xec, 0x5c, 0x15, 0x4f, 0x66, 0x68, 0xc9, 0xc2, + 0xd7, 0xef, 0x0a, 0x57, 0x3a, 0xbc, 0xb8, 0x51, 0xf8, 0xcb, 0x1b, 0x85, 0xff, 0x7d, 0xa3, 0xf0, + 0xdf, 0x6e, 0x15, 0xee, 0xf2, 0x56, 0xe1, 0xae, 0x6e, 0x15, 0xee, 0xf3, 0xeb, 0x16, 0x66, 0xed, + 0x41, 0x53, 0x77, 0x49, 0xcf, 0x48, 0x56, 0xeb, 0x1d, 0xaa, 0x97, 0x93, 0x1d, 0x1d, 0x9a, 0xc6, + 0x97, 0x78, 0x51, 0xc7, 0x2b, 0xb3, 0xb9, 0x1c, 0xef, 0xcc, 0xed, 0xbf, 0x01, 0x00, 0x00, 0xff, + 0xff, 0x5e, 0x61, 0xe5, 0xc6, 0xd0, 0x05, 0x00, 0x00, } func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/types/ccv_test.go b/x/ccv/types/ccv_test.go index c9f97fa13f..51979fb4da 100644 --- a/x/ccv/types/ccv_test.go +++ b/x/ccv/types/ccv_test.go @@ -6,7 +6,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/interchain-security/x/ccv/types" + "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" ) diff --git a/x/ccv/types/errors.go b/x/ccv/types/errors.go index 053ac6f8b4..79c0e1e31c 100644 --- a/x/ccv/types/errors.go +++ b/x/ccv/types/errors.go @@ -1,28 +1,28 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" ) // CCV sentinel errors var ( - ErrInvalidPacketData = sdkerrors.Register(ModuleName, 2, "invalid CCV packet data") - ErrInvalidPacketTimeout = sdkerrors.Register(ModuleName, 3, "invalid packet timeout") - ErrInvalidVersion = sdkerrors.Register(ModuleName, 4, "invalid CCV version") - ErrInvalidChannelFlow = sdkerrors.Register(ModuleName, 5, "invalid message sent to channel end") - ErrInvalidConsumerChain = sdkerrors.Register(ModuleName, 6, "invalid consumer chain") - ErrInvalidProviderChain = sdkerrors.Register(ModuleName, 7, "invalid provider chain") - ErrInvalidStatus = sdkerrors.Register(ModuleName, 8, "invalid channel status") - ErrInvalidGenesis = sdkerrors.Register(ModuleName, 9, "invalid genesis state") - ErrDuplicateChannel = sdkerrors.Register(ModuleName, 10, "CCV channel already exists") - ErrInvalidVSCMaturedId = sdkerrors.Register(ModuleName, 11, "invalid vscId for VSC packet") - ErrInvalidVSCMaturedTime = sdkerrors.Register(ModuleName, 12, "invalid maturity time for VSC packet") - ErrInvalidConsumerState = sdkerrors.Register(ModuleName, 13, "provider chain has invalid state for consumer chain") - ErrInvalidConsumerClient = sdkerrors.Register(ModuleName, 14, "ccv channel is not built on correct client") - ErrInvalidProposal = sdkerrors.Register(ModuleName, 15, "invalid proposal") - ErrInvalidHandshakeMetadata = sdkerrors.Register(ModuleName, 16, "invalid provider handshake metadata") - ErrChannelNotFound = sdkerrors.Register(ModuleName, 17, "channel not found") - ErrClientNotFound = sdkerrors.Register(ModuleName, 18, "client not found") - ErrDuplicateConsumerChain = sdkerrors.Register(ModuleName, 19, "consumer chain already exists") - ErrConsumerChainNotFound = sdkerrors.Register(ModuleName, 20, "consumer chain not found") + ErrInvalidPacketData = errorsmod.Register(ModuleName, 2, "invalid CCV packet data") + ErrInvalidPacketTimeout = errorsmod.Register(ModuleName, 3, "invalid packet timeout") + ErrInvalidVersion = errorsmod.Register(ModuleName, 4, "invalid CCV version") + ErrInvalidChannelFlow = errorsmod.Register(ModuleName, 5, "invalid message sent to channel end") + ErrInvalidConsumerChain = errorsmod.Register(ModuleName, 6, "invalid consumer chain") + ErrInvalidProviderChain = errorsmod.Register(ModuleName, 7, "invalid provider chain") + ErrInvalidStatus = errorsmod.Register(ModuleName, 8, "invalid channel status") + ErrInvalidGenesis = errorsmod.Register(ModuleName, 9, "invalid genesis state") + ErrDuplicateChannel = errorsmod.Register(ModuleName, 10, "CCV channel already exists") + ErrInvalidVSCMaturedId = errorsmod.Register(ModuleName, 11, "invalid vscId for VSC packet") + ErrInvalidVSCMaturedTime = errorsmod.Register(ModuleName, 12, "invalid maturity time for VSC packet") + ErrInvalidConsumerState = errorsmod.Register(ModuleName, 13, "provider chain has invalid state for consumer chain") + ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 14, "ccv channel is not built on correct client") + ErrInvalidProposal = errorsmod.Register(ModuleName, 15, "invalid proposal") + ErrInvalidHandshakeMetadata = errorsmod.Register(ModuleName, 16, "invalid provider handshake metadata") + ErrChannelNotFound = errorsmod.Register(ModuleName, 17, "channel not found") + ErrClientNotFound = errorsmod.Register(ModuleName, 18, "client not found") + ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 19, "consumer chain already exists") + ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 20, "consumer chain not found") ) diff --git a/x/ccv/types/events.go b/x/ccv/types/events.go index 1cab3e8a15..ba71e063f3 100644 --- a/x/ccv/types/events.go +++ b/x/ccv/types/events.go @@ -2,12 +2,13 @@ package types // CCV events const ( - EventTypeTimeout = "timeout" - EventTypePacket = "ccv_packet" - EventTypeChannelEstablished = "channel_established" - EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" - EventTypeConsumerClientCreated = "consumer_client_created" - EventTypeAssignConsumerKey = "assign_consumer_key" + EventTypeTimeout = "timeout" + EventTypePacket = "ccv_packet" + EventTypeChannelEstablished = "channel_established" + EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" + EventTypeConsumerClientCreated = "consumer_client_created" + EventTypeAssignConsumerKey = "assign_consumer_key" + EventTypeRegisterConsumerRewardDenom = "register_consumer_reward_denom" EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" EventTypeFeeDistribution = "fee_distribution" @@ -38,4 +39,7 @@ const ( AttributeDistributionFraction = "distribution_fraction" AttributeDistributionTotal = "total" AttributeDistributionToProvider = "provider_amount" + + AttributeConsumerRewardDenom = "consumer_reward_denom" + AttributeConsumerRewardDepositor = "consumer_reward_depositor" ) diff --git a/x/ccv/types/expected_keepers.go b/x/ccv/types/expected_keepers.go index 172b762228..8176d193b2 100644 --- a/x/ccv/types/expected_keepers.go +++ b/x/ccv/types/expected_keepers.go @@ -47,6 +47,7 @@ type StakingKeeper interface { GetLastTotalPower(ctx sdk.Context) math.Int GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) GetUnbondingType(ctx sdk.Context, id uint64) (unbondingType stakingtypes.UnbondingType, found bool) + BondDenom(ctx sdk.Context) (res string) } type EvidenceKeeper interface { @@ -99,7 +100,10 @@ type ClientKeeper interface { GetSelfConsensusState(ctx sdk.Context, height ibcexported.Height) (ibcexported.ConsensusState, error) } -// TODO: Expected interfaces for distribution on provider and consumer chains +// DistributionKeeper defines the expected interface of the distribution keeper +type DistributionKeeper interface { + FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error +} // ConsumerHooks event hooks for newly bonded cross-chain validators type ConsumerHooks interface { diff --git a/x/ccv/types/shared_params.go b/x/ccv/types/shared_params.go index 4bd5ec4142..8ff676bded 100644 --- a/x/ccv/types/shared_params.go +++ b/x/ccv/types/shared_params.go @@ -57,6 +57,16 @@ func ValidateString(i interface{}) error { return nil } +func ValidateDistributionTransmissionChannel(i interface{}) error { + // Accept empty string as valid, since this means a new + // distribution transmission channel will be created + if i == "" { + return nil + } + // Otherwise validate as usual for a channelID + return ValidateChannelIdentifier(i) +} + func ValidateChannelIdentifier(i interface{}) error { value, ok := i.(string) if !ok { diff --git a/x/ccv/types/utils.go b/x/ccv/types/utils.go index 2da60fa495..f27dab2b04 100644 --- a/x/ccv/types/utils.go +++ b/x/ccv/types/utils.go @@ -5,7 +5,7 @@ import ( "sort" "time" - sdkerrors "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -67,11 +67,11 @@ func SendIBCPacket( ) error { _, ok := channelKeeper.GetChannel(ctx, sourcePortID, sourceChannelID) if !ok { - return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", sourceChannelID) + return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", sourceChannelID) } channelCap, ok := scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePortID, sourceChannelID)) if !ok { - return sdkerrors.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") + return errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") } _, err := channelKeeper.SendPacket(ctx, diff --git a/x/ccv/types/utils_test.go b/x/ccv/types/utils_test.go index dc3a5bba18..1267daf119 100644 --- a/x/ccv/types/utils_test.go +++ b/x/ccv/types/utils_test.go @@ -5,8 +5,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - ibcsimapp "github.com/cosmos/interchain-security/legacy_ibc_testing/simapp" - "github.com/cosmos/interchain-security/x/ccv/types" + ibcsimapp "github.com/cosmos/interchain-security/v2/legacy_ibc_testing/simapp" + "github.com/cosmos/interchain-security/v2/x/ccv/types" "github.com/stretchr/testify/require" )